總算搞懂realloc
阿新 • • 發佈:2019-02-09
今天做資料結構的實驗,又第n次用到realloc。可惜我也第n次感到迷惑
最初接觸realloc時,是學線性表的時候。
書中寫的“在順序線性表L中第i個位置之前插入新的元素 e”
裡面有句話我實在不懂
if(L.length >= L.lisesize) { newbase = (ElemType *)realloc(L.elem,(L.lisesize + LISTINCREMENT) * siezeof (ElemType)); if(!newbase) exit(OVERFLOW); L.elem = newbase; L.listsize += LISTINCREMENT; }
當時想,為什麼要先用 newbase 指向擴大後的記憶體,然後在判斷是否成功後,又令 L.elem 指向 newbase 所指向的記憶體,而不是直接
L.elem = (ElemType *)realloc(L.elem,(L.lisesize + LISTINCREMENT) * siezeof (ElemType));
狠狠的查了一堆文章才知道 realloc 的用法原來如此的不簡單。
首先第一種情況是,如果當前有連續的記憶體塊足夠分配的話,就直接講 L.elem 指向的記憶體空間擴大,使 L.elem 指向新的記憶體地址,並且返回 L.elem 。在這種情況下,newbase 與 L.elem 所指向的地址是一樣的。
但是第二種情況就不一樣了。如果當前沒有足夠的連續記憶體塊用來分配,那就要找到第一個足夠大的地方用來作新的記憶體,並令 newbase 指向它, 然後再將 L.elem 指向的內容複製到 newbase ,free 舊的記憶體,返回 newbase 。 這樣也就發生資料移動了。此時的 newbase 與L.elem 所指向的地址是不一樣的。
因此有時候也可以合理利用 newbase 與 L.elem 的相同與否來進行一些操作。
看回令我感到疑惑的問題,現在看來,這是不嚴謹的寫法。如果資料發生了移動,又令 L.elem 立即指向新的記憶體地址,這麼一來 realloc 就無法根據 L.elem 找回原先的記憶體塊,也因此無法 free 舊的記憶體了,即舊的記憶體的地址丟失,發生記憶體洩露。
嗯,基本上算是搞懂了。