realloc() 用法詳解


原型:extern void *realloc(void *mem_address, unsigned int newsize);

語法: 指針名=( 數據類型*)realloc(要改變內存大小的 指針名,新的大小)。//新的大小一定要大於原來的大小,不然的話會導致數據丟失!
頭文件:#include < stdlib.h> 有些編譯器需要#include <malloc.h>,在TC2.0中可以使用alloc.h頭文件
功能:先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,並且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝到新分配的內存區域,而后釋放原來mem_address所指內存區域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內存區域的首地址。即重新分配存儲器塊的地址。
返回值:如果重新分配成功則返回指向被分配內存的 指針,否則返回空指針NULL。
注意:這里原始內存中的數據還是保持不變的。當內存不再使用時,應使用 free()函數將內存塊釋放。

應用舉例

舉例1:
從這個例子可以看出 realloc函數的功能。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
int *pn=(int *) malloc(5*sizeof(int));
printf("%p\n",pn);
for(i=0;i<5;i++)
scanf("%d",&pn[i]);
pn=(int *)realloc(pn,10*sizeof(int));
printf("%p\n",pn);
for(i=0;i<5;i++)
printf("%3d",pn[i]);
printf("\n");
free(pn);
return 0;
}
舉例2:(在TC2.0中運行通過)
// realloc.c
#include <syslib.h>
#include <alloc.h>
main()
{
char *p;
clrscr(); // clear screen
p=(char *) malloc(100);
if(p)
printf("Memory Allocated at: %x",p);
else
printf("Not Enough Memory!\n");
getchar();
p=(char *)realloc(p,256);
if(p)
printf("Memory Reallocated at: %x",p);
else
printf("Not Enough Memory!\n");
free(p);
getchar();
return 0;
}

詳細說明及注意要點

內存分配情況

<1>如果有足夠空間用於擴大mem_address指向的內存塊,則分配額外內存,並返回mem_address。
這里說的是“擴大”,我們知道,realloc是從堆上分配內存的,當擴大一塊內存空間時, realloc()試圖直接從堆上現存的數據后面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平。也就是說,如果原先的內存大小后面還有足夠的空閑空間用來分配,加上原來的空間大小= newsize。那么就ok。得到的是一塊連續的內存。
<2>如果原先的內存大小后面沒有足夠的空閑空間用來分配,那么從堆中另外找一塊newsize大小的內存。
並把原來大小內存空間中的內容復制到newsize中。返回新的mem_address指針。(數據被移動了)。
老塊被放回堆上。
例如:
#include <malloc.h>
void main()
{
char *p,*q;
p = (char * ) malloc(10);
q = p;
p = (char * ) realloc (q,20); //A行,通過realloc擴大p的空間,並把新的地址賦值給p。
…………………………
}
在這段程序中我們增加了 指針q,用它記錄了原來的 內存地址p。這段程序可以編譯通過,但在執行到A行時,如果原有內存后面沒有足夠空間將原有空間擴展成一個連續的新大小的話, realloc函數就會以第二種方式分配內存,此時數據發生了移動,那么所記錄的原來的 內存地址q所指向的內存空間實際上已經放回到堆上了!這樣就會產生q 指針指針懸掛,即指針指向了一塊沒有分配給用戶使用的內存,如果再用q指針進行操作就可能發生意想不到的問題。所以在應用 realloc函數是應當格外注意這種情況。

返回情況

返回的是一個void類型的 指針:調用成功。(這就要求在你需要的時候進行 強制類型轉換
返回NULL:當需要擴展的大小(第二個參數)為0並且第一個參數不為NULL時。此時原內存變成“ free(游離)”的了。
返回NULL:當沒有足夠的空間可供擴展的時候。此時,原內存空間的大小維持不變。

特殊情況

如果mem_address為NULL,則realloc()和 malloc()類似。分配一個newsize的內存塊,返回一個指向該內存塊的 指針
如果newsize大小為0,那么釋放mem_address指向的內存,並返回NULL。
如果沒有足夠可用的內存用來完成重新分配(擴大原來的內存塊或者分配新的內存塊),則返回NULL。而原來的內存塊保持不變。

realloc使用總結

1. realloc失敗的時候,返回NULL
2. realloc失敗的時候,原來的內存不改變,不會釋放也不會移動
3. 假如原來的內存后面還有足夠多剩余內存的話,realloc的內存=原來的內存+剩余內存,realloc還是返回原來內存的地址; 假如原來的內存后面沒有足夠多剩余內存的話,realloc將申請新的內存,然后把原來的內存數據拷貝到新內存里,原來的內存將被 free掉,realloc返回新內存的地址
4. 如果size為0,效果等同於 free()。這里需要注意的是只對 指針本身進行釋放,例如對二維指針**a,對a調用realloc時只會釋放一維,使用時謹防 內存泄露
5. 傳遞給realloc的 指針必須是先前通過 malloc(), calloc(), 或realloc()分配的
6.傳遞給realloc的 指針可以為空,等同於 malloc
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM