在 C 語言中,陣列在宣告時即為指標常數,其記憶體空間在編譯階段便已確定分配。然而,現實開發中程式往往無法預知所需陣列的確切長度。若預先分配過大空間會造成記憶體浪費,若過小則導致溢位風險。為此,C 語言提供了動態內存分配機制,允許程式在執行期根據實際需求向堆區申請與釋放記憶體,極大提升了程式的靈活性與健壯性。
void *malloc(size_t size);
分配指定位元組數的記憶體塊,返回指向該塊起始位址的 void* 指標。分配失敗時返回 NULL。參數為所需總位元組數,常搭配 sizeof 使用,如 malloc(10 * sizeof(int))。
void *calloc(size_t num_elements, size_t element_size);
分配 num_elements * element_size 位元組,並將所有位元初始化為 0。參數分離為「元素個數」與「單一元素大小」,語意更清晰,適合陣列分配場景。
void *realloc(void *ptr, size_t new_size);
改變已分配記憶體塊的大小。若 ptr == NULL,行為等同 malloc(new_size);若 new_size == 0,行為等同 free(ptr)。擴容時可能移動記憶體位置,故必須用返回值更新指標。
void free(void *pointer);
將由 malloc、calloc、realloc 返回的記憶體歸還給堆區。嚴禁 對非動態分配指標(如棧上陣列、字串常量)呼叫 free,亦不可重複釋放同一指標。
NULL,直接解引用會導致崩潰。int *arr = malloc(10 * sizeof(int));
if (arr == NULL) exit(EXIT_FAILURE);free 會破壞堆管理結構,導致程式崩潰。free(ptr) 後 ptr 成為懸空指標,再次解引用行為不可預期。釋放後建議置 NULL:free(ptr); ptr = NULL;動態分配的記憶體在不再使用時未釋放,即構成記憶體洩漏。長期運行的程式(如伺服器、嵌入式裝置)會因洩漏耗盡可用記憶體導致崩潰。原則:malloc/calloc/realloc 每一次呼叫,必須有對應的 free,且僅釋放一次。
int 在 16/32/64 位元系統長度不同,永遠寫 sizeof(int) 而非硬編碼 2/4/8。| 函數 | 用途 | 關鍵行為 |
|---|---|---|
| malloc | 原始分配 | 不初始化,失敗返回 NULL |
| calloc | 零初始化分配 | 自動歸零,參數分離為個數×大小 |
| realloc | 調整大小 | 可能移動記憶體,必須接收返回值 |
| free | 釋放 | 僅接受三大分配函數返回的指標 |