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

C語言動態內存管理精講:malloc/calloc/realloc/free 完全指南

     編輯:關於C語言

內存區域速覽

區域特點典型內容
棧自動管理,函數調用分配/釋放,速度快,空間小局部變量、函數參數、返回地址
堆手動管理,malloc/free,空間大,易產生碎片動態分配內存
靜態/全局區程序啟動分配,結束釋放全局變量、static 變量、字面量

四大核心函數原型與用法

1. malloc(size_t size) — 原始分配

void *malloc(size_t size);  // 返回 void*,需強轉
int *p = (int *)malloc(10 * sizeof(int));
if (!p) { /* 處理失敗 */ }
  • 不初始化內存(垃圾值)。
  • 失敗返回 NULL,必須檢查。

2. calloc(size_t nmemb, size_t size) — 零初始化分配

void *calloc(size_t nmemb, size_t size);  // 分配 nmemb * size 字節並清零
int *arr = (int *)calloc(100, sizeof(int));  // 等價 malloc(400) + memset(0)
  • 自動清零,適合數組/結構體初始化。
  • 內部可能優化(如映射零頁),比 malloc+memset 更快。

3. free(void *ptr) — 釋放

free(p);
p = NULL;  // 防止野指針,雙重釋放
  • 只能釋放 malloc/calloc/realloc 返回的地址。
  • 釋放後指針不自動置 NULL,手動置 NULL 是良習。
  • 釋放 NULL 安全無操作。

4. realloc(void *ptr, size_t size) — 調整大小

void *realloc(void *ptr, size_t size);
  • 若擴容:嘗試原地擴展,否則分配新塊、拷貝、釋放舊塊。
  • 陷阱:p = realloc(p, new_size); 若失敗返回 NULL,原 p 丟失 → 內存洩漏!
  • 正確模式:
    void *tmp = realloc(p, new_size);
    if (!tmp) { /* 錯誤處理,p 仍有效 */ }
    else p = tmp;
    

typedef 輔助類型定義(提升可移植性)

typedef unsigned char  uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int   uint32_t;
typedef unsigned long long uint64_t;
// 推薦直接 #include  使用標準類型

位域:節省空間的利器

struct flags {
    unsigned int a : 1;  // 1 bit
    unsigned int   : 2;  // 2 bit 填充/保留
    unsigned int b : 3;
    unsigned int c : 2;
};  // 共 8 bits = 1 字節
  • 位域長度不能超過底層類型位寬。
  • :0 強制下一位域從新字節開始。
  • 位域不取地址,不可用指針指向。

避坑指南:內存洩漏四大元兇

  1. 忘記 free:動態分配無釋放路徑。
  2. realloc 失敗未保留舊指針(上文詳述)。
  3. 指針算術導致丟失基址:p++ 後無法 free,務必保存原指針。
  4. 早釋放/多釋放:使用後置 NULL、引用計數或智能指針(C++)管理生命週期。

工具推薦

  • Valgrind:valgrind --leak-check=full ./prog 精準定位洩漏。
  • AddressSanitizer:gcc -fsanitize=address 編譯期插桿,運行時檢測越界/使用後釋放。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved