1. 程式人生 > >realloc 使用詳解(分析realloc invalid pointer、指標無效等錯誤)

realloc 使用詳解(分析realloc invalid pointer、指標無效等錯誤)

realloc函式用來為ptr重新分配大小為size的一塊記憶體,看似很簡單,在使用過程中卻會發生各種錯誤。

函式形式為:
void * realloc ( void * ptr, size_t new_size );
下面是我畫出的函式流程圖

realloc 函式流程圖

這個函式的工作流程:
1.對ptr進行判斷,如果ptr為NULL,則函式相當於malloc(new_size),試著分配一塊大小為new_size的記憶體,如果成功將地址返回,否則返回NULL。如果ptr不為NULL,則進入2
2.檢視ptr是不是在堆中,如果不是的話會跑出異常錯誤,會發生realloc invalid pointer(具體原因在後面講)。如果ptr在堆中,則檢視new_size大小,如果new_size大小為0,則相當於free(ptr),講ptr指標釋放,返回NULL,如果new_size小於原大小,則ptr中的資料可能會丟失,只有new_size大小的資料會儲存(這裡很重要),如果size等於原大小,等於啥都沒做,如果size大於原大小,則看ptr所在的位置還有沒有足夠的連續記憶體空間,如果有的話,分配更多的空間,返回的地址和ptr相同,如果沒有的話,在更大的空間內查詢,如果找到size大小的空間,將舊的內容拷貝到新的記憶體中,把舊的記憶體釋放掉,則返回新地址,否則返回NULL。
這裡解釋一下,為什麼ptr要在堆中,學過編譯原理的同學應該都知道C語言中的malloc,realloc,calloc()這種使用者主動分配的記憶體放在堆區,而臨時變數放在棧區,這是兩塊不同的區域。堆區的變數由使用者通過free釋放空間,而棧區的變數在函式退出後就自動釋放,所以這兩個區域的變數生存時間不同,不能相互間進行記憶體分配操作。所以要求ptr必須在堆區,即ptr必須是malloc,realloc或者calloc的返回值,要不然可以為NULL,把realloc變為malloc。
所以使用realloc函式應該注意一下幾點:
1.ptr必須為NULL,或者為malloc,realloc或者calloc的返回值,否則發生realloc invalid pointer
錯誤
2.new_size如果小於old_size,只有new_size大小的資料會被儲存,可能會發生資料丟失,慎重使用。
3.如果new_size大於old_size,可能會分配一塊新的記憶體,這時候ptr指向的記憶體會被釋放,ptr成為野指標,再訪問的時候會發生錯誤。
4.最後不要將返回結果再賦值給ptr,即ptr=realloc(ptr,new_size)是不建議使用的,因為如果記憶體分配失敗,ptr會變為NULL,如果之前沒有將ptr所在地址賦給其他值的話,會發生無法訪問舊記憶體空間的情況,所以建議使用temp=realloc(ptr,new_size)。
參考文章: