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

C語言動態內存管理全解析:malloc、calloc、realloc、free 實戰指南

     編輯:關於C語言

靜態 vs 動態存儲分配

靜態分配:編譯期根據定義預分配固定大小內存,生命周期固定。
動態分配:運行期按需申請(malloc/calloc)、釋放(free)、調整(realloc),靈活高效,適用於數據規模不可預知場景。需包含<stdlib.h>。

核心四大函數詳解

malloc / free

void *malloc(size_t size);  // 分配size字節,成功返回起始地址,失敗返回NULL
void free(void *ptr);       // 釋放ptr指向的動態內存,ptr必須來自malloc/calloc/realloc
  • 返回void*,使用時需強制類型轉換:(int*)malloc(sizeof(int))。
  • 分配的內存無初始值(垃圾數據)。
  • 若不確定類型大小,務必用sizeof:p = malloc(n * sizeof(*p)),利於移植。
  • free後指針變為野指針,良習:free(p); p = NULL;。

calloc

void *calloc(size_t nmemb, size_t size); // 分配nmemb個size字節元素,自動清零
  • 相當於分配一維數組,首地址即數組名。
  • 內容初始化為全0(整數0、浮點0.0、指針NULL)。
  • 釋放同用free。

realloc

void *realloc(void *ptr, size_t size); // 調整已分配塊大小,可能移動內存
  • 擴容時新增部分未初始化;縮容保留原有數據。
  • 若ptr==NULL等同malloc;size==0實現視庫而定(可能釋放或返回唯一指針)。
  • 調用後必須用返回值更新指針,原指針可能失效。

實戰案例:動態數組排序

需求:輸入三個整數,動態分配存儲,升序輸出。

int *p1 = malloc(sizeof(int));
int *p2 = malloc(sizeof(int));
int *p3 = malloc(sizeof(int));
if (p1 && p2 && p3) {
    scanf("%d%d%d", p1, p2, p3);
    // 簡單交換排序
    if (*p1 > *p2) swap(p1, p2);
    if (*p1 > *p3) swap(p1, p3);
    if (*p2 > *p3) swap(p2, p3);
    printf("%d %d %d\n", *p1, *p2, *p3);
}
free(p1); free(p2); free(p3);

關鍵點:分配後檢查NULL、使用sizeof而非魔數、用完釋放。

常見陷阱與最佳實踐

  • 忘記檢查NULL:分配失敗直接解引用導致崩潰。
  • 越界訪問:寫入超出分配大小,破壞堆元數據。
  • 重複釋放/釋放野指針:雙重free或free非堆指針。
  • 內存洩漏:丟失指針導致無法釋放。
  • 類型大小硬編碼:用malloc(4)代替malloc(sizeof(int)),移植性差。

建議:封裝安全分配宏/函數,統一錯誤處理;大塊分配考慮mmap;嵌入式環境關注碎片整理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved