C語言第三十三彈---動態內存管理(上)

?個人主頁:?熬夜學編程的小林

💗系列專欄:?【C語言詳解】?【數據結構詳解】

動態內存管理

1、為什么要有動態內存分配

2、malloc和free

2.1、malloc

2.2、free

3、calloc和realloc

3.1、calloc

3.2、realloc

4、常見的動態內存的錯誤

總結


1、為什么要有動態內存分配

我們已經掌握的內存開辟方式有:
int val = 20;//在棧空間上開辟四個字節
char arr[10] = {0};//在棧空間上開辟10個字節的連續空間
但是上述的開辟空間的方式有兩個特點:
? 空間開辟大小是固定的。
? 數組在申明的時候,必須指定數組的長度,數組空間?旦確定了大小不能調整
但是對于空間的需求,不僅僅是上述的情況。有時候我們需要的空間大小在程序運行的時候才能知
道,那數組的編譯時開辟空間的方式就不能滿足了。
C語言引入了動態內存開辟,讓程序員自己可以申請和釋放空間,就比較靈活了。

2、malloc和free

2.1、malloc

C語言提供了?個動態內存開辟的函數:
void* malloc (size_t size);//size為字節數
這個函數向內存申請一塊連續可用的空間,并返回指向這塊空間的指針。
? 如果開辟成功,則返回?個指向開辟好空間的指針。
? 如果開辟失敗,則返回?個 NULL 指針,因此malloc的返回值?定要做檢查。
? 返回值的類型是 void* ,所以malloc函數并不知道開辟空間的類型,具體在使用的時候使用者自己來決定。
? 如果參數 size 為0,malloc的行為是標準是未定義的,取決于編譯器。

2.2、free

C語言提供了另外?個函數free,專門是用來做動態內存的釋放和回收的,函數原型如下:
void free (void* ptr);
free函數用來釋放動態開辟的內存。
? 如果參數 ptr 指向的空間不是動態開辟的,那free函數的行為是未定義的。
? 如果參數 ptr 是NULL指針,則函數什么事都不做。
malloc和free都聲明在 stdlib.h 頭文件中。
舉個例子:
#include <stdio.h>
#include <stdlib.h>
int main()
{int num = 0;scanf("%d", &num);int arr[num] = {0};int* ptr = NULL;ptr = (int*)malloc(num*sizeof(int));if(NULL != ptr)//判斷ptr指針是否為空 不為空則賦值{int i = 0;for(i=0; i<num; i++){*(ptr+i) = 0;}}free(ptr);//釋放ptr所指向的動態內存ptr = NULL;//是否有必要? 建議手動置空,防止野指針問題return 0;
}

指針釋放之后是否要手動置空,博主的建議是最好手動置空,防止出現野指針。

3、calloc和realloc

3.1、calloc

C語言還提供了?個函數叫 calloc calloc 函數也用來動態內存分配。原型如下:
void* calloc (size_t num, size_t size);
? 函數的功能是為 num 個大小為 size 的元素開辟?塊空間,并且把空間的每個字節初始化為0。
? 與函數 malloc 的區別只在于 calloc 會在返回地址之前把申請的空間的每個字節初始化為全0。
舉個例子:
#include <stdio.h>
#include <stdlib.h>
int main()
{int *p = (int*)calloc(10, sizeof(int));if(NULL != p){int i = 0;for(i=0; i<10; i++){printf("%d ", *(p+i));}}free(p);p = NULL;return 0;
}
輸出結果:
所以如果我們對申請的內存空間的內容要求初始化,那么可以很方便的使用calloc函數來完成任務。

3.2、realloc

? realloc函數的出現讓動態內存管理更加靈活。
? 有時會我們發現過去申請的空間太小了,有時候我們又會覺得申請的空間過大了,那為了合理的時候內存,我們?定會對內存的大小做靈活的調整。那 realloc 函數就可以做到對動態開辟內存大小的調整。
函數原型如下:
void* realloc (void* ptr, size_t size);
? ptr 是要調整的內存地址
? size 調整之后新大小(字節數)
? 返回值為調整之后的內存起始位置。
? 這個函數調整原內存空間大小的基礎上,還會將原來內存中的數據移動到新的空間。
? realloc在調整內存空間的是存在兩種情況:
? 情況1:原有空間之后有足夠大的空間
? 情況2:原有空間之后沒有足夠大的空間
情況1
當是情況1 的時候,要擴展內存就直接原有內存之后直接追加空間,原來空間的數據不發生變化。
情況2
當是情況2 的時候,原有空間之后沒有足夠多的空間時,擴展的方法是:在堆空間上另找?個合適大小的連續空間來使用。這樣函數返回的是?個新的內存地址。
由于上述的兩種情況,realloc函數的使用就要注意?些
#include <stdio.h>
#include <stdlib.h>
int main()
{int* ptr = (int*)malloc(100);if (ptr != NULL){//業務處理}else{return 1;}//擴展容量//代碼1 - 直接將realloc的返回值放到ptr中ptr = (int*)realloc(ptr, 1000);//這樣可以嗎?(如果申請失敗會如何?)// realloc可能申請空間失敗,因此不推薦直接賦值給ptr,// 而是創建一個臨時指針變量,如果確定申請成功再將臨時指針變量賦值給ptr,即代碼2方式//代碼2 - 先將realloc函數的返回值放在p中,不為NULL,在放ptr中int* p = NULL;p = realloc(ptr, 1000);if (p != NULL){ptr = p;// 推薦使用該方式,防止空間申請失敗情況}//業務處理free(ptr);return 0;
}

總結:動態開辟的空間建議不要直接賦值給想要處理數據的指針變量,而是先判斷再進行賦值。

4、常見的動態內存的錯誤

1、對NULL指針的解引用操作

void test(){int *p = (int *)malloc(INT_MAX/4);*p = 20;//如果p的值是NULL,就會有問題free(p);}

2、對動態開辟空間的越界訪問

void test(){int i = 0;int *p = (int *)malloc(10*sizeof(int));if(NULL == p){exit(EXIT_FAILURE);}for(i=0; i<=10; i++){*(p+i) = i;//當i是10的時候越界訪問}free(p);}

3、對非動態開辟內存使用free釋放

void test(){int a = 10;int *p = &a;free(p);//ok? free只能釋放動態開辟的內存空間}

4、使用free釋放一塊動態開辟內存的一部分

void test(){int *p = (int *)malloc(100);p++;free(p);//p不再指向動態內存的起始位置}

5、對同一塊動態內存多次釋放

void test(){int *p = (int *)malloc(100);free(p);free(p);//重復釋放}

6、動態開辟內存忘記釋放(內存泄漏)

void test(){int *p = (int *)malloc(100);if(NULL != p){*p = 20;}}
int main(){test();while(1);}
忘記釋放不再使用的動態開辟的空間會造成內存泄漏。
切記:動態開辟的空間?定要釋放,并且正確釋放。

總結


本篇博客就結束啦,謝謝大家的觀看,如果公主少年們有好的建議可以留言喔,謝謝大家啦!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711794.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711794.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711794.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

氣象數據收集

1、國家氣象科學數據中心 預報數據:需要定制,收費10萬+ 觀測數據:國家氣象信息中心-中國氣象數據網 (cma.cn)https://data.cma.cn/data/cdcdetail/dataCode/A.0012.0001.html 地面基本氣象觀測數據 滯后2天 滯后一天 路面數據同化系統,實時 國家氣象信息中心-中國氣象數…

11.以太網交換機工作原理

目錄 一、以太網協議二、以太網交換機原理三、交換機常見問題思考四、同網段數據通信全過程五、跨網段數據通信全過程六、關鍵知識七、調試命令 前言&#xff1a;在網絡中傳輸數據時需要遵循一些標準&#xff0c;以太網協議定義了數據幀在以太網上的傳輸標準&#xff0c;了解以…

android移動應用開發基礎答案,安卓工程師面試題

一線企業的app都是多線程和多進程的&#xff0c;而Android進程間通信機制就是Binder&#xff0c;原生的線程間通信則是Handler&#xff0c;Binder和Handler是了解安卓運行機制必須要掌握的一個知識點&#xff0c;更是一線企業面試必問的知識點&#xff01; 以下幾道就是大廠關于…

【QT+QGIS跨平臺編譯】之五十五:【QGIS_CORE跨平臺編譯】—【qgsmeshcalcparser.cpp生成】

文章目錄 一、Bison二、生成來源三、構建過程一、Bison GNU Bison 是一個通用的解析器生成器,它可以將注釋的無上下文語法轉換為使用 LALR (1) 解析表的確定性 LR 或廣義 LR (GLR) 解析器。Bison 還可以生成 IELR (1) 或規范 LR (1) 解析表。一旦您熟練使用 Bison,您可以使用…

Unity中URP實現水體(整理優化)

文章目錄 前言一、優化水的深度1、我們把 水流動的方向 和 水深淺過渡值&#xff0c;整合到一個四維變量中2、修改 水體流動方向3、在片元著色器中&#xff0c;修改使用過渡變量 二、優化泡沫三、優化水下的扭曲1、修復原本擾動UV的計算 四、優化水面高光1、把高光強度、光滑度…

紅隊基礎設施建設

文章目錄 一、ATT&CK二、T1583 獲取基礎架構2.1 匿名網絡2.2 專用設備2.3 滲透測試虛擬機 三、T1588.002 C23.1 開源/商用 C23.1.1 C2 調研SliverSliver 對比 CS 3.1.2 CS Beacon流量分析流量規避免殺上線 3.1.3 C2 魔改3.1.4 C2 隱匿3.1.5 C2 準入應用場景安裝配置說明工具…

UC++對象方法IsValid()、IsValidLowLevel()、IsValidLowLevelFast()的區別

在 Unreal Engine 中&#xff0c;IsValid(), IsValidLowLevel(), 和 IsValidLowLevelFast() 是用于檢查 UObject&#xff08;Unreal Object&#xff09;有效性的三個不同的方法。它們之間的區別主要在于檢查的級別和效率。 IsValid()&#xff1a; 檢查級別&#xff1a; IsVal…

深度學習 精選筆記(2)自動求導與概率

學習參考&#xff1a; 動手學深度學習2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、請聯系侵刪。 ②已寫完的筆記文章會不定時一直修訂修改(刪、改、增)&#xff0c;以達到集多方教程的精華于一文的目的。 ③非常推薦上面&#xff08;學習參考&#x…

Linux系統——LAMP架構

目錄 一、LAMP架構組成 1.LAMP定義 2.各組件的主要作用 3.CGI和FastCGI 3.1CGI 3.3CGI和FastCGI比較 4.PHP 4.1PHP簡介 4.2PHP的Opcode語言 4.3PHP設置 二、LAMP架構實現 1.編譯安裝Apache httpd服務 2.編譯安裝Mysql 3.編譯安裝PHP 4.安裝論壇 5.搭建博客 W…

Linux編程 2.4 文件和目錄-Linux文件系統結構

1、文件操作基本元素 文件操作相關的最基本元素是&#xff1a;目錄結構、索引節點和文件的數據本身。 目錄結構&#xff08;目錄項&#xff09;索引節點&#xff08;i節點&#xff09;文件的數據 2、文件系統的三個區域 屬性&#xff1a; 超級塊&#xff1a;存放文件系統本身…

vs code快捷鍵

ShiftCtrlO vs code 提供很強大的功能&#xff0c;就是可以快速查文件中的符號列表和函數列表&#xff0c;我們首先打開一個源碼文件&#xff0c;比tcp.c&#xff0c;然后我們通過快捷鍵“ShiftCtrlO”即可打開對應源碼文件的符號列表和函數列表&#xff0c;通過查看這些列表&a…

【學習心得】Python調用JS的三種常用方法

在做JS逆向的時候&#xff0c;一種情況是直接用Python代碼復現JS代碼的功能&#xff0c;達成目的。但很多時候這種方法有明顯的缺點&#xff0c;那就是一旦JS代碼邏輯發生了更改&#xff0c;你就得重寫Python的代碼邏輯非常不便。于是第二種情況就出現了&#xff0c;我直接得到…

python自動化管理和zabbix監控網絡設備(防火墻和python自動化配置部分)

目錄 前言 一、ssh配置 1.FW1 2.core-sw1 3.core-sw2 二、python自動化配置防火墻 三、驗證DNAT 四、驗證DNAT 前言 視頻演示請訪問b站主頁 白帽小丑的個人空間-白帽小丑個人主頁-嗶哩嗶哩視頻 一、ssh配置 給需要自動化管理的設備配置ssh服務端用戶名和密碼 1.FW1 …

純css實現-讓字符串在文字少時顯示為居中對齊,而在文字多時顯示為左對齊

純css實現-讓字符串在文字少時顯示為居中對齊&#xff0c;而在文字多時顯示為左對齊 使用flex實現 思路 容器樣式&#xff08;.container&#xff09;: Flex容器的BFC性質使得其內部的子元素&#xff08;.text-box&#xff09;在水平方向上能夠居中&#xff0c;通過justify-c…

生態環境數據分析新篇章:Meta分析、R語言、Matlab、貝葉斯、結構方程模型等的前沿實踐

目錄 ①Meta分析在生態環境領域里的應用 ②R語言在生態環境領域中的應用 ③MATLAB在生態環境數據處理與分析中的應用 ④基于R語言piecewiseSEM結構方程模型在生態環境應用 ⑤R語言貝葉斯方法在生態環境領域中的高階技術應用 更多應用 為了Meta分析問題的設計、基礎理論、…

【菜鳥入門!】Matlab零基礎快速入門教程

數學建模競賽中&#xff0c;編程軟件是必不可缺少的&#xff0c;比如大家都熟知的MATLAB多數同學們都會經常用到&#xff0c;今天給大家介紹一些MATLAB的基本元素&#xff0c;希望幫助大家更好的掌握編寫基本的函數&#xff01; 變量和數組 MATLAB 程序的基本數據單元是數組。一…

rm刪除未釋放空間,linux sync有時不起作用

此時需要重啟系統即可. Linux中的sync命令用于將文件系統的緩沖區數據立即寫入磁盤&#xff0c;以確保數據的持久性。123456 sync命令沒有任何選項&#xff0c;簡單執行即可。它會將文件系統緩沖區中的數據寫入磁盤&#xff0c;并更新文件系統的超級塊及其他元數據。使用sync命…

Vue.js的雙向綁定原理

Vue的雙向綁定 vue雙向綁定是其最重要的核心亮點&#xff0c;其原理也很簡單&#xff0c;這里做個簡單總結 vue2的雙向綁定是利用的Object.definePropertyvue3的雙向綁定是利用的 ES6Porxy中的defineProperty(target, propKey, propDesc 其作用類似于Object.defineProperty …

您想要擁有 Apple Vision Pro 的原因

自從2024年2月2日Apple Vision Pro發布以來&#xff0c;網上已經有很多關于如何使用這款蘋果最新設備的示例。該平臺引入的空間計算新世界能夠完成許多在其他設備上無法完成的事情。Reddit 上的這個人能夠以 51202160 的分辨率從他的 PC 上串流游戲&#xff01;在本文中&#x…

SpringMVC01、回顧MVC

1、回顧MVC 1.1、什么是MVC MVC是模型(Model)、視圖(View)、控制器(Controller)的簡寫&#xff0c;是一種軟件設計規范。是將業務邏輯、數據、顯示分離的方法來組織代碼。MVC主要作用是降低了視圖與業務邏輯間的雙向偶合。MVC不是一種設計模式&#xff0c;MVC是一種架構模式。…