動態記憶體開闢的函式有malloc、realloc、calloc、free函式,接下來對每乙個函式進行解釋及使用,並總結出幾個經典的例子鞏固,以及總結常見的錯誤。
1.malloc & free基本使用
int main()
//...
free(p);
p = null;
return 0;
}
2.realloc & free基本使用
int main()
//...
ptr = realloc(p, 120);
if (ptr != null)
free(p);
p = null;
return 0;
}
realloc一般用於malloc後邊空間不可用,重新開闢乙個空間。
3.calloc & free基本使用
int main()
calloc函式有兩個引數,分別為個數、位元組大小,並且初始化全為0
注意:realloc(null,10) ; 等價於 malloc(10) ;
現在就幾個經典的例子來講一下動態記憶體開闢中經常出現的錯誤
典例1:
void getmemory(char *p, int num)
void test(void)
int main()
程式崩潰,記憶體洩露。
分析:1.在test函式內部,str以值傳遞的形式給getmemory函式,getmemory函式形參p是str的乙份臨時拷貝,在getmemory函式內部用p接收動態開闢好記憶體位址,str並沒有發生變化,等getmemory函式返回之後,str依然保持空指標,strcpy將「hello」拷貝到null,訪問記憶體出錯。
2.p所指向的空間找不到了,所以存在記憶體洩露問題。
更改:
void getmemory(char **p, int num)
void test(void)
int main()
典例2:
用函式返回值來傳遞動態記憶體
char* getmemory(int num)
void test(void)
int main()
典例3:
char *getstring(void)
void test(void)
int main()
產生乙個隨機值。
分析:在test函式內部,指標變數str是空指標,呼叫getstring函式,在getstring函式內部建立乙個陣列,裡邊的內容是「hello world」,p是乙個區域性變數,返回存放的位址,函式呼叫結束,記憶體釋放,「hello world」銷毀。str可以指向,但不能訪問。就不能輸出,「hello world」。
典例4:
int main()
return 0;
}
分析:p被free後其位址仍然不變,p所指的內容被釋放,p就成了野指標。應該將p置為null。
而這裡沒有起到防護作用,拷貝的時候就出錯。
總結(常見錯誤):
1.對空指標進行解引用
2.記憶體訪問越界
3.釋放非動態開闢記憶體
4.釋放動態記憶體一部分
5.釋放同一塊動態記憶體多餘1次
6.忘記釋放
動態記憶體開闢
記憶體分配有三種方式 1.從靜態儲存區分配,生命週期隨程式的結束而結束,比如全域性變數,static變數 2.從棧空間分配,函式呼叫完其被自動釋放 3.從堆空間分配,即動態記憶體開闢,比如 malloc,calloc,realloc,何時申請何時釋放 malloc 函式原型void malloc s...
動態記憶體開闢
記憶體分配有三種方式 1.從靜態儲存區分配,生命週期隨程式的結束而結束,比如說全域性變數,static變數 2.從棧空間分配,函式呼叫完成後被自動釋放 3.從對空間分配,即動態記憶體開闢,比如malloc,calloc,realloc malloc calloc realloc和free mallo...
動態記憶體開闢
1.記憶體分配方式 三種 1 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的 整個執行期間都存在。例如全域性變數,static 變數。2 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的...