realloc

realloc

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

基本介紹

  • 中文名:動態記憶體調整
  • 外文名:reset allocation
  • 別稱:realloc
  • 原型:extern void *realloc
函式說明,語法,頭檔案,功能,返回值,注意,相關函式,套用舉例,舉例1,舉例2,記憶體分配,返回情況,特殊情況,使用總結,

函式說明

語法

指針名=(數據類型*)realloc(要改變記憶體大小的指針名,新的大小)。
新的大小可大可小(如果新的大小大於原記憶體大小,則新分配部分不會被初始化;如果新的大小小於原記憶體大小,可能會導致數據丟失)

頭檔案

#include <stdlib.h> 有些編譯器需要#include <malloc.h>,在TC2.0中可以使用alloc.h頭檔案

功能

先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,並且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝到新分配的記憶體區域,而後釋放原來mem_address所指記憶體區域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的記憶體區域的首地址。即重新分配存儲器塊的地址。

返回值

如果重新分配成功則返回指向被分配記憶體的指針,否則返回空指針NULL。

注意

當記憶體不再使用時,應使用free()函式將記憶體塊釋放。

相關函式

malloc、calloc、free、_alloca

套用舉例

舉例1

從這個例子可以看出realloc函式的功能。
運行環境:ubuntu 12.04 GCC 4.6.3
運行結果:
malloc 0x904f008
realloc 0x904f008
0 1 2 3 4 5 6 7 8 9
#include<stdio.h>#include<stdlib.h>int main(){inti;int*pn=(int*)malloc(5*sizeof(int));if (!pn) {    printf("malloc fail\n");    exit(-1);}printf("malloc%p\n",pn);for(i=0;i<5;i++)pn[i]=i;pn=(int*)realloc(pn,10*sizeof(int));if (!pn) {    printf("realloc fail\n");    exit(-1);}printf("realloc%p\n",pn);for(i=5;i<10;i++)pn[i]=i;for(i=0;i<10;i++)printf("%3d",pn[i]);free(pn);pn = NULL;return 0;}

舉例2

:(在TC2.0中運行通過)
//realloc.c#include<syslib.h>#include<alloc.h>main(){char*p;clrscr();//clearscreenp=(char*)malloc(100);if(p)printf("MemoryAllocatedat:%x",p);elseprintf("NotEnoughMemory!\n");getchar();p=(char*)realloc(p,256);if(p)printf("MemoryReallocatedat:%x",p);elseprintf("NotEnoughMemory!\n");free(p);getchar();return 0;}

記憶體分配

  1. 如果有足夠空間用於擴大mem_address指向的記憶體塊,則分配額外記憶體,並返回mem_address。
    這裡說的是“擴大”,我們知道,realloc是從堆上分配記憶體的,當擴大一塊記憶體空間時, realloc()試圖直接從堆上現存的數據後面的那些位元組中獲得附加的位元組,如果能夠滿足,自然天下太平。也就是說,如果原先的記憶體大小後面還有足夠的空閒空間用來分配,加上原來的空間大小= newsize。那么就ok。得到的是一塊連續的記憶體。
  2. 如果原先的記憶體大小後面沒有足夠的空閒空間用來分配,那么從堆中另外找一塊newsize大小的記憶體。
    並把原來大小記憶體空間中的內容複製到newsize中。返回新的mem_address指針。(數據被移動了)。
    老塊被放回堆上。
例如
#include<malloc.h>voidmain(){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。而原來的記憶體塊保持不變。
現存的數據然後就被拷貝至新的位置,而老塊則放回到堆上.重要的信息就是數據可能被移動
#include <stdio.h>
#include <malloc.h>
int main(int argc, char* argv[])
{
char *p,*q;
p = (char *)malloc(10);
q = p;
p = (char *)realloc(p,10);
printf("p=0x%x/n",p);
printf("q=0x%x/n",q);
return 0;
}
輸出結果:realloc後,記憶體地址不變
p=0x431a70
q=0x431a70
例2:
#include <stdio.h>
#include <malloc.h>
int main(int argc, char* argv[])
{
char *p,*q;
p = (char *)malloc(10);
q = p;
p = (char *)realloc(p,1000);
printf("p=0x%x/n",p);
printf("q=0x%x/n",q);
return 0;
}
輸出結果:realloc後,記憶體地址發生了變化
p=0x351c0
q=0x431a70

使用總結

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。

相關詞條

熱門詞條

聯絡我們