1. 程式人生 > >C語言動態記憶體管理malloc、calloc、realloc、free的用法和注意事項

C語言動態記憶體管理malloc、calloc、realloc、free的用法和注意事項

此文是參考http://www.cplusplus.com/reference/cstdlib/裡的動態記憶體管理部分所寫,如發現有問題和不足之處,請參看原文,最好能幫忙指出,謝謝。

1.void* malloc (size_t size);

malloc:分配一塊size Byte大小的記憶體,返回一個指向該塊記憶體開始的指標,指標型別是void。
其中size_t代表無符號整形型別

例如:

int *number;
number = (int *)malloc(sizeof(int));//分配一個大小為sizeof(int)的儲存空間,
//返回的指標需要強轉成需要的型別
if(NULL == number)//判斷呼叫是否成功,不成功就退出
{
    exit(0);
}
*number = 100;//記憶體裡的內容沒有被初始化,值不確定,這裡要記得初始化
free(number);//用完之後要free,釋放記憶體
number = NULL;//防止出現野指標
如果size是0,那麼返回值不確定,取決於不同庫的實現,但是返回值必定是不能引用的。
如果呼叫失敗,則返回空指標

2.void* calloc (size_t num, size_t size);

calloc:為一個大小為num的陣列分配記憶體,每個元素的大小是size,把每個元素初始化為0
int *number;
int i = 0;
number = (int *)calloc(3,sizeof(int));//分配一個大小為3*sizeof(int)的儲存空間,
//返回的指標需要強轉成需要的型別
if(NULL == number)//判斷呼叫是否成功,不成功就退出
{
    exit(0);
}
for(;i<3;i++)
{
    printf(“address:%d number[%d] = %d\n”,&number[i],i,number[i]);//列印結果是0
}
free(number);//用完之後要free,釋放記憶體
number = NULL;//防止出現野指標
如果size是0,那麼返回值不確定,取決於不同庫的實現,但是返回值必定是不能引用的。
如果呼叫失敗返回空指標。

3.void* realloc (void* ptr, size_t size);

realloc:改變ptr指向的記憶體空間的大小,把指向的記憶體空間的內容移動到新空間裡(地址通過函式返回,可能指向原來的地址也可能指向新地址)
ptr指向的記憶體空間必須是通過malloc、calloc、realloc函式分配的!!!如果ptr是空指標,那麼realloc函式的malloc的功能是一樣的。
int * number;
int * renumber;
number = (int *)calloc(5,sizeof(int))
if(NULL == number)//判斷呼叫是否成功,不成功就退出
{
    exit(0);
}

renumber = (int *)realloc(number,3*sizeof(int));
if(NULL != renumber)//如果分配成功,就讓number指向新分配的記憶體,這樣不會造成記憶體洩漏,
{ //因為number原來指向的記憶體已經被自動回收。
    number = renumber;
}
renumber = NULL;
...
free(number);//這裡只需要free number就可以了。
number = NULL;
如果size為0:
1.在C90(C++98)標準裡,會回收ptr指標指向的記憶體,並且返回空指標。
2.在C99(C++11)標準裡,會返回一個不能被引用的地址(不確定是不是空指標,取決於不同的庫實現)

如果函式呼叫失敗,會返回一個空指標,ptr所指向記憶體也不會被回收,即會保持原來的ptr不變(地址不變,內容不變)。

如果返回的是空指標:
1.在C90(C++98)標準裡可能性有兩種:
1).size為0(ptr指向的地址將會被回收);
2).函式沒有申請到記憶體空間(ptr指向的地址將不會改變)
2.在C99(C++11)標準裡只有一種可能:函式申請記憶體空間失敗(此處好像和上面的說法有一點點衝突)

4.void free (void* ptr);

free:回收記憶體
如果ptr不是通過malloc、calloc、realloc函式分配的,會造成不可預測的行為。
如果ptr為空,那麼free函式不作任何處理。
int * buffer1, * buffer2, * buffer3;
buffer1 = (int*) malloc (100*sizeof(int));
buffer2 = (int*) calloc (100,sizeof(int));
buffer3 = (int*) realloc (buffer2,500*sizeof(int));
free (buffer1);
free (buffer3);
注:此處是上文所說的衝突的具體原因,
在C99(C++11)裡,上面說的如果size為0,返回的不一定是空指標(有可能是有可能不是,決定於具體庫的實現,也就是說可能會有庫返回的是空指標),最後又說,如果返回是空指標的話,是因為申請記憶體失敗(這地方就是矛盾的地方)。