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

realloc 使用詳解(分析realloc invalid pointer、指針無效等錯誤)【轉】

strong 開源 堆區 找到 失敗 temp idt googl 發生

來源:http://www.cnblogs.com/ladd/archive/2012/06/30/2571420.html
realloc函數用來為ptr重新分配大小為size的一塊內存,看似很簡單,在使用過程中卻會發生各種錯誤。

函數形式為:
void * realloc ( void * ptr, size_t new_size );
最近在網上查看了一些資料,在glibc中沒有找到具體的實現(有人找到了可以發給我,[email protected]),查到了一個開源項目自己寫的realloc代碼,http://code.google.com/p/mallocspethmeniel/source/browse/trunk/realloc.c?r=23,應該和stdlib裏面的實現流程一樣。
下面是我畫出的函數流程圖

技術分享

這個函數的工作流程:
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)。
參考文章:
1.function realloc  http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/
2.realloc.c http://code.google.com/p/mallocspethmeniel/source/browse/trunk/realloc.c?r=23

以上內容為ladd原創,畫流程圖花了老長時間,如果轉載請註明出處:http://www.cnblogs.com/ladd/archive/2012/06/30/2571420.html

realloc 使用詳解(分析realloc invalid pointer、指針無效等錯誤)【轉】