為什麼會有動態記憶體分配?
這是因為當你宣告乙個陣列時,你必須使用乙個編譯時常量指定陣列的長度,但是,陣列的長度常常在執行時才知道,這是因為它所需要
的記憶體空間取決於輸入資料。而且這種方法人為的進行了陣列大小的限制。
動態記憶體分配:
(堆區):是由程式設計師自己主動申請並釋放的(在執行時開闢的空間)
1.malloc(申請大塊記憶體)原型:
void *malloc( size_tsize);
一般最好寫為malloc(sizeof(type)*nums)的形式
注意:malloc和free必須成對使用。
否則會導致記憶體洩漏(記憶體洩漏對常駐程序的影響最大)
將空間free後需要將指標置空,避免產生野指標。
malloc是以位元組申請空間的,並且申請的空間會比實際要申請的空間大一些,多出來的空間一般儲存申請的空間的一些資訊,比如申請的空間大小。
需注意:
1.判斷申請的空間是否成功。
2.free後也應該將該指標置空。
3.使用申請的空間後的內容會出錯,就是訪問的內容越界。
2.calloc(功能相當於malloc+memset的功能):分配空間並會將空間初始化為0
函式原型如下:
void *calloc( size_tnum, size_tsize);
缺點:由於要進行初始化,所以比起malloc,它的效率較低。
3.realloc:修改原先已經分配好的記憶體塊的大小。
函式原型如下:
void *realloc( void *memblock, size_tsize);
使用的一般方式例如:
int *p = (int *)malloc(10*sizeof(int));
int *q =realloc (p,48);
free(q);-------注意,這時只需要free乙個指標q就可以了。
這裡的q必須有效,q為乙個null 指標或者是由calloc,malloc,realloc所申請的。
使用realloc需要注意的問題:
1.當第乙個引數為乙個空指標時,它的功能就類似於malloc函式。
2.當第乙個引數不為空時,並且它原先的記憶體塊後面還有大量的空間可以使用時:這時直接擴充套件空間的大小。
3.當第乙個引數不為空,但是它原先的記憶體塊後面沒有足夠的空間可供使用時,將尋找其他地方重新開闢一段空間,如果可以找到足夠大的空間開闢需要的空間大小時,那麼就在其他地方重新開闢空間,並將原先記憶體塊的內容拷貝到那塊空間。而如果已經沒有足夠大的空間供你重新開闢的話,那麼就擴充套件記憶體失敗,返回null;
4.如果開闢的空間還要小於原先的記憶體塊時,那麼將會其他地方重新開闢空間,並將內容拷貝下來,將後面的的記憶體塊進行部分釋放。
realloc的正確使用方法:
(以防realloc擴充套件空間時,擴充套件失敗,返回乙個null,如果直接把返回值賦給先前已開闢好的空間的指標變數,可能會改變已經分配好空間的指標變數,所以先將realloc擴充套件空間的返回值儲存在另乙個指標變數中)。
#define _crt_secure_no_warnings 1
#include#include#include#includeint main()
realp = (char *)realloc(p,20 * sizeof(char));
if (null == realp)
else
free(p);
system("pause");
return 0;
}
常見的動態記憶體使用錯誤:
1.對乙個null指標進行解引用。
2.對分配的記憶體進行操作時越過邊界,這點類似與陣列的越過邊界訪問產生的錯誤。
3.釋放並非動態分配的記憶體。
4.試圖釋放一塊動態分配的記憶體的一部分以及一塊動態記憶體被釋放後被繼續使用。
動態記憶體分配
在c 中建立乙個物件時,我們必須要為這個物件申請一塊記憶體,而且要用建構函式對這塊記憶體進行初始化。c 中的new和delete相對於c的庫函式malloc和free在這方面有很大的優勢,所以我們主要講的是運算子new和delete。當用new來建立乙個物件時,它會自動在堆裡為物件分配記憶體並且為這...
動態記憶體分配
為什麼使用動態記憶體分配?c語言中的一切操作都是基於記憶體的 變數和陣列都是記憶體的別名,如何分配這些記憶體由編譯器在編譯期間決定 定義陣列的時候必須指定陣列唱的 而陣列長度是在編譯期就必須決定的 需求 程式執行的過程中,可能需要使用一些額外的記憶體空間 malloc和free malloc和fre...
動態記憶體分配
c的儲存類別有4種 自動的 auto 靜態的 statics 暫存器的 register 外部的 extern 全域性變數時分配在記憶體中的靜態儲存區 靜態區域性變數屬於靜態儲存類別,在靜態儲存區內分配儲存單元,是在編譯時賦初值的,只賦初值一次,在程式執行時它已有初值,以後每次呼叫函式時不再重新賦初...