malloc、calloc區別 分配在哪裏

函數malloc()和calloc()都可以用來動態分配內存空間,但兩者稍有區別。

  • malloc()函數有一個參數,即要分配的內存空間的大小: void*malloc(size_tsize);
  • calloc()函數有兩個參數,分別爲元素的數目和每個元素的大小,這兩個參數的乘積就是要分配的內存空間的大小。void*calloc(size_tnumElements,size_tsizeOfElement);

如果調用成功,函數malloc()和函數calloc()都將返回所分配的內存空間的首地址。

 

兩函數的主要區別是malloc()不能初始化所分配的內存空間,而calloc() 能。如果由malloc()函數分配的內存空間原來沒有被使用過,則其中的每一位可能都是0;反之, 如果這部分內存曾經被分配過,則其中可能遺留有各種各樣的數據。也就是說,使用malloc()函數的程序開始時(內存空間還沒有被重新分配)能正常進行,但經過一段時間(內存空間還已經被重新分配)可能會出現問題。

函數calloc() 會將所分配的內存空間中的每一位都初始化爲零,也就是說,如果你是爲字符類型或整數類型的元素分配內存,那麼這些元素將保證會被初始化爲0;如果你是爲指針類型的元素分配內存,那麼這些元素通常會被初始化爲空指針;如果你爲實型數據分配內存,則這些元素會被初始化爲浮點型的零。

malloc用於申請一段新的地址,參數size爲需要內存空間的長度,如:

char* p;

p=(char*)malloc(20);

calloc與malloc相似,參數nelem爲申請地址的單位元素長度,elsize爲元素個數,如:

char* p;

p=(char*)calloc(sizeof(char),20);

這個例子與上一個效果相同

 

realloc()給一個已經分配了地址的指針重新分配空間,參數ptr爲原有的空間地址,newsize是重新申請的地址長度。如:

char* p;

p=(char*)malloc(sizeof(char)*20);

p=(char*)realloc(p,sizeof(char)*40);

注意,這裏的空間長度都是以字節爲單位。 

 

C語言的標準內存分配函數:malloc,calloc,realloc,free等。

malloc與calloc的區別爲1塊與n塊的區別

l  malloc調用形式爲(類型*)malloc(size):在內存的動態存儲區中分配一塊長度爲“size”字節的連續區域,返回該區域的首地址。

l  calloc調用形式爲(類型*)calloc(n,size):在內存的動態存儲區中分配n塊長度爲“size”字節的連續區域,返回首地址。

l  realloc調用形式爲(類型*)realloc(*ptr,size):將ptr內存大小增大到size

l  free的調用形式爲free(void*ptr):釋放ptr所指向的一塊內存空間

l  C++中爲new/delete函數。

malloc的功能是確保內存空間使用字節。比如限定100,函數使用方法:(char *)malloc(100) ,超過100就會出錯

程序例:

#include <stdlib.h>

#include <stdio.h>

//#include <malloc.h>

void main( void )

{

 char *str;

 str = (char *)malloc(100);

 if( str == NULL )

  printf( "不能確保內存領域。/n" );

 else

  printf( "可以確保100字節內存。/n" );

 free( str ); 

 printf( "解放內存。/n" );

 getchar();

}

------------------------------------------------------------------

calloc則限定了每個要素的內存使用字節量

例:(char *)calloc(4,100);

程序例:

#include <stdlib.h>

#include <stdio.h>

//#include <malloc.h>

void main( void )

{

 char *str;

 str = (char *)calloc(4,100);

 if( str == NULL )

  printf( "不能確保內存領域。/n" );

 else

  printf( "可以確保4x100字節內存。/n" );

 free( str );

 printf( "解放內存。/n" );

 getchar();

}

首先看個問題程序(這裏用的是TC編譯器):

#include "stdlib.h"

#include "stdio.h"

void main()

{

   int *i;

   i=(int *)malloc(sizeof(int));

   *i=1;

   *(i+1)=2;

   printf("%x|%d/n",i,*i);

   printf("%x|%d",i+1,*(i+1));

}

輸出的結果是:

8fc|1

8fe|2

這個程序編譯通過,運行正常,說它有問題,問題出在哪呢?

首先通過malloc,建了一個大小爲2的堆,i指向的地址是8fc,i+1指向的地址是8fc+sizeof(int)=8fe但是地址8fe是不受保護的,因爲它不是機器分配給i+1的,隨時會被其他變量佔用

正確的做法是

#include "stdlib.h"

#include "stdio.h"

void main()

{

   int *i;

   i=(int *)malloc(sizeof(int));

   *i=1;

   i=(int *)realloc(i,2*sizeof(int));

   *(i+1)=2;

   printf("%x|%d/n",i,*i);

   printf("%x|%d",i+1,*(i+1));

}

realloc 可以對給定的指針所指的空間進行擴大或者縮小,無論是擴張或是縮小,原有內存的中內容將保持不變。當然,對於縮小,則被縮小的那一部分的內容會丟失realloc 並不保證調整後的內存空間和原來的內存空間保持同一內存地址。相反,realloc 返回的指針很可能指向一個新的地址

所以,在代碼中,我們必須將realloc返回的值,重新賦值給 p :

p = (int *) realloc (p, sizeof(int) *15);

甚至,你可以傳一個空指針(0)給 realloc ,則此時realloc 作用完全相當於malloc

int* p = (int *) realloc (0,sizeof(int) * 10);  //分配一個全新的內存空間,

這一行,作用完全等同於:

int* p = (int *) malloc(sizeof(int) * 10);

『附註:TC編譯器裏sizeof(int)=2,VC裏面sizeof(int)=4;char型在兩個編譯器裏是一樣的,都是1個字節(8位)』

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章