C語言動態記憶體管理malloc、calloc、realloc、free的用法和注意事項
阿新 • • 發佈:2019-01-02
此文是參考http://www.cplusplus.com/reference/cstdlib/裡的動態記憶體管理部分所寫,如發現有問題和不足之處,請參看原文,最好能幫忙指出,謝謝。
其中size_t代表無符號整形型別
如果呼叫失敗,則返回空指標
如果呼叫失敗返回空指標。
ptr指向的記憶體空間必須是通過malloc、calloc、realloc函式分配的!!!如果ptr是空指標,那麼realloc函式的malloc的功能是一樣的。
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)標準裡只有一種可能:函式申請記憶體空間失敗(此處好像和上面的說法有一點點衝突)
如果ptr不是通過malloc、calloc、realloc函式分配的,會造成不可預測的行為。
如果ptr為空,那麼free函式不作任何處理。
在C99(C++11)裡,上面說的如果size為0,返回的不一定是空指標(有可能是有可能不是,決定於具體庫的實現,也就是說可能會有庫返回的是空指標),最後又說,如果返回是空指標的話,是因為申請記憶體失敗(這地方就是矛盾的地方)。
1.void* malloc (size_t size);
malloc:分配一塊size Byte大小的記憶體,返回一個指向該塊記憶體開始的指標,指標型別是void。其中size_t代表無符號整形型別
例如:
如果size是0,那麼返回值不確定,取決於不同庫的實現,但是返回值必定是不能引用的。int *number; number = (int *)malloc(sizeof(int));//分配一個大小為sizeof(int)的儲存空間, //返回的指標需要強轉成需要的型別 if(NULL == number)//判斷呼叫是否成功,不成功就退出 { exit(0); } *number = 100;//記憶體裡的內容沒有被初始化,值不確定,這裡要記得初始化 free(number);//用完之後要free,釋放記憶體 number = NULL;//防止出現野指標
如果呼叫失敗,則返回空指標
2.void* calloc (size_t num, size_t size);
calloc:為一個大小為num的陣列分配記憶體,每個元素的大小是size,把每個元素初始化為0如果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;//防止出現野指標
如果呼叫失敗返回空指標。
3.void* realloc (void* ptr, size_t size);
realloc:改變ptr指向的記憶體空間的大小,把指向的記憶體空間的內容移動到新空間裡(地址通過函式返回,可能指向原來的地址也可能指向新地址)ptr指向的記憶體空間必須是通過malloc、calloc、realloc函式分配的!!!如果ptr是空指標,那麼realloc函式的malloc的功能是一樣的。
如果size為0: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;
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,返回的不一定是空指標(有可能是有可能不是,決定於具體庫的實現,也就是說可能會有庫返回的是空指標),最後又說,如果返回是空指標的話,是因為申請記憶體失敗(這地方就是矛盾的地方)。