C語言之內存管理(一)

1.一般來說,我們可以簡單地理解爲內存分爲3個部分:堆,棧和靜態區。堆棧就是棧,而不是堆。堆的英文是heap;棧的英文是stack,也翻譯爲堆棧。
1)堆:由malloc系列函數或new操作符分配的內存。其生命週期又free或delete決定,在沒有釋放之前一直存在,直到程序結束。其特點是使用靈活,空間比較大,但容易出錯。
2)棧:保存局部變量。棧上的內容只在函數的範圍內存在,當函數運行結束,這些內容也會自行銷燬。其特點是效率高,但空間大小有限。
3)靜態區:自動保存全局變量和static變量(包括static全局和局部變量)。靜態區的內容在整個生命週期內存在,由編譯器在編譯的時候分配。
4)指針沒有指向一塊合法的內存,定義了指針變量,但是沒有爲指針分配內存,即指針沒有指向一塊合法的內存
1°結構體成員未初始化

struct
{
    char *name;
    int score
}stu,*pstu;
int main()
{
    strcpy(stu.name,"Tom");
    stu.score = 99;
    return 0;
}
很多初學者犯了這個錯誤不知道是怎麼回事,這裏定義了結構體變量stu,但是他沒想到這個結構體內部char* name,該成員在定義結構體變量stu時,只是給name這個指針變量分配了四個字節,name指針本身沒有指向一個合法的地址,這時候其內部存的都是一些亂碼,所以在調用strcpy函數時,會將字符串“Tom”往亂碼裏所指的內存上覆制,而這塊內存name指針根本就無權訪問,導致出錯,解決的方法是爲name指針malloc一塊空間
2°沒有爲結構體指針分配足夠的內存
3°函數的入口檢驗
不管什麼時候,我們使用指針之前一定要確保指針是有效的。
一般在函數入口處使用assert(NULL != p)對參數進行檢查,在非參數的地方使用if(NULL != p)來校驗。但這裏都有一個要求,即p在定義的時候同時初始化爲NULL。
assert是一個宏。而不是函數,包含在assert.h 頭文件中,這個宏只在Debug版本上起作用,而在Release版本中被編譯器完全優化掉,這樣就不會影響代碼的性能。


發佈了75 篇原創文章 · 獲贊 45 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章