編輯本段C語言函數realloc

函數簡介

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

應用舉例

  舉例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
  …………………………
  }
  在這段程序中我們增加了指針q,用它記錄了原來的內存地址p。這段程序可以編譯通過,但在執行到A行時,如果原有內存後面沒有足夠空間將原有空間擴展成一個連續的新大小的話,realloc函數就會以第二種方式分配內存,此時數據發生了移動,那麼所記錄的原來的內存地址q所指向的內存空間實際上已經放回到堆上了!這樣就會產生q指針的指針懸掛,如果再用q指針進行操作就可能發生意想不到的問題。所以在應用realloc函數是應當格外注意這種情況。
  3、返回情況
  返回的是一個void類型的指針,調用成功。(這就在你需要的時候進行強制類型轉換
  返回NULL,當需要擴展的大小(第二個參數)爲0並且第一個參數不爲NULL,此時原內存變成了“freed(遊離)”的了。
  返回NULL,當沒有足夠的空間可供擴展的時候,此時,原內存空間的大小維持不變。
  4、特殊情況
  如果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。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章