首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言動態內存分配完全指南:malloc、calloc、realloc 與 free 深度解析

     編輯:關於C

前言:為什麼需要動態內存分配?

在 C 語言中,陣列在宣告時即為指標常數,其記憶體空間在編譯階段便已確定分配。然而,現實開發中程式往往無法預知所需陣列的確切長度。若預先分配過大空間會造成記憶體浪費,若過小則導致溢位風險。為此,C 語言提供了動態內存分配機制,允許程式在執行期根據實際需求向堆區申請與釋放記憶體,極大提升了程式的靈活性與健壯性。

核心函數詳解

1. malloc - 基礎記憶體分配

void *malloc(size_t size);

分配指定位元組數的記憶體塊,返回指向該塊起始位址的 void* 指標。分配失敗時返回 NULL。參數為所需總位元組數,常搭配 sizeof 使用,如 malloc(10 * sizeof(int))。

2. calloc - 初始化為零的分配

void *calloc(size_t num_elements, size_t element_size);

分配 num_elements * element_size 位元組,並將所有位元初始化為 0。參數分離為「元素個數」與「單一元素大小」,語意更清晰,適合陣列分配場景。

3. realloc - 動態調整記憶體大小

void *realloc(void *ptr, size_t new_size);

改變已分配記憶體塊的大小。若 ptr == NULL,行為等同 malloc(new_size);若 new_size == 0,行為等同 free(ptr)。擴容時可能移動記憶體位置,故必須用返回值更新指標。

4. free - 釋放記憶體

void free(void *pointer);

將由 malloc、calloc、realloc 返回的記憶體歸還給堆區。嚴禁 對非動態分配指標(如棧上陣列、字串常量)呼叫 free,亦不可重複釋放同一指標。

四大經典陷阱與防範對策

  1. 未檢查 malloc 返回值
    分配失敗返回 NULL,直接解引用會導致崩潰。
    正確做法:
    int *arr = malloc(10 * sizeof(int));
    if (arr == NULL) exit(EXIT_FAILURE);
  2. 越界訪問
    讀寫超出分配範圍屬於未定義行為,輕則資料損壞,重則安全漏洞。嚴格維護邊界檢查。
  3. 釋放非動態分配指標
    對棧記憶體、全域變數、字串常量呼叫 free 會破壞堆管理結構,導致程式崩潰。
  4. Use-after-free(釋放後使用)
    free(ptr) 後 ptr 成為懸空指標,再次解引用行為不可預期。釋放後建議置 NULL:free(ptr); ptr = NULL;

記憶體洩漏:隱形殺手

動態分配的記憶體在不再使用時未釋放,即構成記憶體洩漏。長期運行的程式(如伺服器、嵌入式裝置)會因洩漏耗盡可用記憶體導致崩潰。原則:malloc/calloc/realloc 每一次呼叫,必須有對應的 free,且僅釋放一次。

工程實踐建議

  • 消除硬編碼限制:動態分配讓資料結構大小由執行期資料決定,而非編譯期常數。
  • 善用 sizeof 保證可移植性:int 在 16/32/64 位元系統長度不同,永遠寫 sizeof(int) 而非硬編碼 2/4/8。
  • 配對檢查:代碼審查時,對每個分配點尋找對應釋放點,確保路徑覆蓋完整。

快速參考表

函數用途關鍵行為
malloc原始分配不初始化,失敗返回 NULL
calloc零初始化分配自動歸零,參數分離為個數×大小
realloc調整大小可能移動記憶體,必須接收返回值
free釋放僅接受三大分配函數返回的指標
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved