指標動態申請記憶體的錯誤分析

2021-04-22 23:48:01 字數 1374 閱讀 3746

指標動態申請記憶體的錯誤有幾種解釋,

有如下幾種:

相信我們都知道傳值呼叫引數時,不改變實際引數的值。原理:形參是實參的乙個copy(副本),而不是指向同一塊記憶體位址。於是用指標或引用就可以解決這個問題,大多數時候還會節省記憶體開銷,因為不用作副本拷貝。

這樣乙個例子:

void test(char *ps)

int main(void)

用指標作為引數,在函式內部申請動態記憶體,結果該程式會崩潰。

原因其實很簡單,ps申請了記憶體,也就是改變了ps這個副本的內容(即申請的動態記憶體位址),但函式返回了,原形參ps的內容沒有任何改變,就如同上述的傳值一樣,ps的內容仍為null,於是出錯。

而且不但出錯,該程式還會出現記憶體洩露的問題,因為malloc的這塊記憶體未釋放,也無法釋放了。

試圖用指標引數申請動態記憶體

毛病出在函式getmemory 中.編譯器總是要為函式的每個引數製作臨時副本,指標

引數p 的副本是 _p,編譯器使 _p = p.如果函式體內的程式修改了_p 的內容,就導致

引數p 的內容作相應的修改.這就是指標可以用作輸出引數的原因.在本例中,_p 申請

了新的記憶體,只是把_p 所指的記憶體位址改變了,但是p 絲毫未變.所以函式getmemory

並不能輸出任何東西.事實上,每執行一次getmemory 就會洩露一塊記憶體,因為沒有用

free 釋放記憶體.

感覺上面說的不是很好理解。我把我的理解寫一下。

像第二種說法所說,編譯器總是要為函式的每個引數製作臨時副本,指標

引數p 的副本是 _p,編譯器使 _p = p.這就是指標可以用作輸出引數的原因.

把這個原因解釋一下:

比如你傳入乙個指標p指向的位址是0xffff,那麼複製出來的_p指向的位址也是0xffff,

只不過p和_p本身的儲存位址是不一樣的。例如p存在記憶體位址為1的地方,而_p存在位址2這個地方,

但二者指向的記憶體位址是一致的,所以當修改了_p所指向的位址的內容的時候(也就是修改0xffff,這個位址的內容的時候)

p所指的記憶體內容也改變了,所以該變的內容就可以傳出來了。函式結束_p被刪除,但是這不影響p指向內容的修改。

在申請動態記憶體這個放麵呢,是不一樣的。

在函式外p為null,

在函式內申請動態記憶體,相當於_p=(char *)malloc(10*sizeof(char));

這樣把新申請的記憶體位址賦給了_p,比如新申請的記憶體位址為0xaaaa,那麼現在_p所指向的記憶體位址就是0xaaaa,

但是這不能影響p所指向的位址,因為p和_p是在不同的記憶體位址存放的,現在只有_p的內容改變了,

也就是說記憶體位址為2的這塊位址的內容發生了改變。

p所指的記憶體位址仍為null.所以不能申請出來動態記憶體。

記憶體與指標 動態申請記憶體

1 malloc 標頭檔案malloc.h 一維記憶體申請 型別識別符號 變數 變數名 型別識別符號 malloc sizeof 型別識別符號 陣列大小 二維記憶體申請 型別識別符號 變數 變數名 型別識別符號 malloc sizeof 型別識別符號 陣列行大小 for int i 0 i 陣列行...

指向指標的指標申請動態記憶體

在 高質量c程式設計指南 中,提到了如果函式的引數是乙個指標,那麼別指望它能申請動態記憶體。如下 include include void getmemory char p,int num int main void getmemory char p,int num 最後的輸出的stu的結果是0,即...

動態申請的指標陣列的記憶體申請和釋放問題

char ppchar 0 void fun void main delete ppchar 釋放ppchar負責的記憶體空間 endif char array 10 未知行 每行10列 char arr 2 10 2行 每行10列 for int i 0 i 2 i delete arr 對二維陣...