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

C 語言記憶體分配三大方式:靜態區、堆疊、堆完整解析

     編輯:關於C語言

三大分配方式對比

方式區域生命週期管理者典型例子容量限制
靜態分配靜態儲存區程式啟動~結束編譯器全域變數、static 變數編譯期固定
堆疊分配Stack函數呼叫~返回編譯器/CPU區域變數、函數參數較小(通常 1~8 MB)
堆分配Heap手動控制程式設計師malloc/free, new/delete虛擬記憶體上限

常見記憶體錯誤與解決方案

1. 分配失敗卻使用

int* p = malloc(n * sizeof(int));
if (p == NULL) return -1; // 必須檢查
// 或 assert(p != NULL);

2. 未初始化就引用

  • 誤以為預設為 0(僅靜態/全域變數保證為 0)。
  • 分配後立即 memset 或逐一賦值初始化。

3. 邊界越界(Off-by-one)

for (i = 0; i <= n; i++) a[i] = 0; // 錯誤:應為 i < n
for (i = 0; i < n; i++) a[i] = 0;  // 正確

4. 記憶體洩漏

  • 每次呼叫洩漏一塊,累積耗盡記憶體導致程式突然死亡。
  • 嚴格遵循「誰分配誰釋放」,配對 malloc/free、new/delete、new[]/delete[]。

5. 釋放後繼續使用(懸空指標/野指標)

free(p); 
p = NULL; // 必須置空,避免誤用
  • 複雜擁有關係導致不確定是否已釋放 → 重構資料結構,明確擁有權。
  • 回傳區域變數位址 → 堆疊記憶體函數結束即銷毀,嚴禁回傳。

關鍵認知釐清

  • sizeof(p) 回傳的是**指標變數大小**(4/8 位元組),**非指向記憶體大小**。記憶體大小需分配時自行記錄。
  • 陣列作參數退化為指標:void foo(int arr[]) 等價 void foo(int* arr),sizeof(arr) 在函數內為指標大小。
  • 指標銷毀 ≠ 記憶體釋放;記憶體釋放 ≠ 指標變為 NULL。兩者獨立。

處理「記憶體耗盡」三策略

  1. 檢查 NULL 後 return 錯誤碼。
  2. 檢查 NULL 後 exit(1) 終止程式。
  3. 為 new/malloc 設定自訂異常處理函數(std::set_new_handler)。

現代 C++ 建議

盡量使用 std::vector、std::string、std::unique_ptr、std::shared_ptr 等 RAII 容器/智慧指標,將記憶體管理交給編譯器,從源頭消除上述錯誤。

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