作者tropical72 (藍影)
看板C_and_CPP
標題Re: [問題] free 與 pointer 的問題
時間Wed Jan 19 01:36:41 2011
※ 引述《way111078 (wei)》之銘言:
: int *addLines;
: addLines = realloc(addLines, (pointCount)*sizeof(int));
如 love 大所說,上面這行會爆,
int *addLines = NULL; 再調用好些。
: *(addLines + (pointCount-1)) = currentPoint;
: 請問大大free的時候
: 1.只要寫free(addLines);就好了嗎?
: 2.addLines指在被realloc記憶體的區塊哪一個位址都可以被free嗎?
這裡要說明 realloc 實際動作,
int *a = NULL, *b=NULL;
a = (int*)malloc(sizeof(int)*10);
b = (int*)realloc(a, sizeof(int)*20); // ---> 注意這行
free(b);
實際上第三行只是把 a 重新 resize 成 20,前面 10 個 size 的值會保留,
重點是在於 "resize" 這個動作,
會先去看 a 的位置夠不夠 resize 成 20 個 size,
如果可以的話就在原本的位置 resize,
如果不行的話會再找其它可以放 20 個 int 的位置,再把 a 的 10 個 int 搬過去,
接著自動釋放舊的空間。然而,上面即使 b 對 a 進行 realloc,事實上
a 和 b 是對同一塊 memory 做管理。
所以下面這段寫法是危險的
int *a=NULL;
a = (int*)malloc(sizeof(int)*10);
(int*)realloc(a, sizeof(int)*20); // ---> 如果是換到新的位置去的話就爆了
第三行便要改成
a = (int*)realloc(a, sizeof(int)*20);
至於您說 free 的問題,我想了解以上各點之後,你就沒這方面問題了,
不論是
b = (int*)realloc(a, sizeof(int)*20); // (1)
或是
a = (int*)realloc(a, sizeof(int)*20); // (2)
在第一段 (1) (b=...realloc(a,...)) 中,事實上所管理的都是同一段記憶體,
但這裡要注意,如果 a 空間不夠, b 會另外找新的空間,所以你應該是要
free(b),而不是 free(a)。如果是程式 realloc 到新的空間而你又 free(a)
這時候才會爆,這個錯不容易抓出來。
(簡單的說,如果 realloc 到新空間, realloc 時就已經把 a free 掉、
搬到 b 去了,這時也只能對 b 做釋放;如果是 realloc 到原空間,
那對 a 還是對 b 做 free 都是可以的。避免這種困擾,還是統一 free b)
至於第二段 (2) 就不用說了,只能 free(a)
另外再提醒,不論是 malloc 或是 realloc,失敗都是傳回 NULL,
這時便不可進行釋放。
上面的述敘中,我想你也注意到了,用 realloc 時會 "參考舊的位置",
這是您這段碼要注意的地方。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.76.142
※ 編輯: tropical72 來自: 180.177.76.142 (01/19 01:40)
推 way111078:第一二行會爆的原因是沒給他初始值嗎? 01/19 01:42
→ tropical72:realloc 會去參考舊的位址,你不給初值它要參考哪? 01/19 01:43
推 legnaleurc:realloc 會根據給它的指標指向哪裡而有不同的操作 01/19 01:43
→ legnaleurc:給它一個垃圾值是沒有用的 01/19 01:44
→ james732:應該要先做malloc再做realloc吧? 為什麼直接realloc呢? 01/19 01:46
→ tropical72:正常的確是j大所說先用malloc再realloc,不過也只用re~ 01/19 01:52
推 legnaleurc:因為 realloc 可以做 malloc 和 free 的動作吧我猜 01/19 01:52
※ 編輯: tropical72 來自: 180.177.76.142 (01/19 02:01)
推 way111078:若上面代碼 b+1(指到下一個位址) 01/19 01:56
→ way111078:再寫free(b); 這樣是可以free的@@? 01/19 01:57
→ james732:是我的話絕對不會做free(b+1)這種事...XD 01/19 01:58
→ james732:會發生什麼事實在沒有人知道 01/19 01:58
→ way111078:不好意思問了很多奇怪的問題@@ 01/19 01:59
→ way111078:是沒有這樣用...只是不知道會發生什麼事情... 01/19 01:59
→ james732:寫程式多思考是好的 值得鼓勵 (Y) 01/19 02:00
→ way111078:或許應該自己寫code跑跑看 01/19 02:00
→ tropical72:抱歉一開始回文時漏了一點, 修正了 free 的對象 01/19 02:03
推 loveme00835:不要用試誤法阿..要先看函式對引數有什麼要求, 他可為 01/19 02:10
→ loveme00835:你達成的工作, 還有回傳值的種類, 這些了解之後你才有 01/19 02:11
→ loveme00835:呼叫他的資格 01/19 02:11
推 way111078:好的!再繼續研究,先謝謝各位大大的熱心指點了 m(_ _)m 01/19 02:16