論calloc和malloc的區別

函數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);
callocmalloc相似,參數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語言的標準內存分配函數:malloccallocreallocfree等。
malloccalloc的區別爲1塊與n塊的區別:
malloc調用形式爲(類型*)malloc(size):在內存的動態存儲區中分配一塊長度爲“size”字節的連續區域,返回該區域的首地址。
calloc調用形式爲(類型*)calloc(nsize):在內存的動態存儲區中分配n塊長度爲“size”字節的連續區域,返回首地址。
realloc調用形式爲(類型*)realloc(*ptrsize):將ptr內存大小增大到size
free的調用形式爲free(void*ptr):釋放ptr所指向的一塊內存空間。
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指向的地址是8fci1指向的地址是8fc+sizeof(int)=8fe
但是地址8fe是不受保護的,因爲它不是機器分配給i1的,隨時會被其他變量佔用。
正確的做法是
#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)=2VC裏面sizeof(int)=4
char型在兩個編譯器裏是一樣的,都是1個字節(8位)』
callocmalloc相似,參數nelem爲申請地址的單位元素長度,elsize爲元素個數,:
char* p;
p=(char*)calloc(sizeof(char),20);
這個例子與上一個效果相同

原文來自:http://blog.csdn.net/jlccl/archive/2007/05/23/1622834.aspx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章