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

C++ 堆記憶體 管理全攻略:malloc/free 與 new/delete 深度對比

     編輯:VC 教學

堆記憶體是什麼?

堆是執行期動態分配的記憶體區域,大小不固定、生命週期由程式設計師手動控制。相對於棧(自動變數、函式呼叫幀),堆適合:

  • 執行期才能決定大小的陣列/物件。
  • 跨函式/作用域共享的資源。
  • 大型物件避免棧溢位。

C 風格:malloc / free

#include <cstdlib>  // 或 

int main() {
    int n; cin >> n;
    int* arr = static_cast<int*>(malloc(n * sizeof(int))); // 返回 void*,需強轉
    if (!arr) { /* 處理分配失敗 */ }

    for (int i = 0; i < n; ++i) arr[i] = i;
    for (int i = 0; i < n; ++i) cout << arr[i] << ',';
    cout << endl;

    free(arr);  // 必須配對釋放,否則洩漏
}

關鍵點

  • malloc 僅分配原始位元組,**不呼叫建構子**。
  • free 僅釋放記憶體,**不呼叫解構子**。
  • 適用於 POD 類型(int, struct 等無建構/解構邏輯)。
  • C++ 代碼中**不推薦**用於類別物件。

C++ 風格:new / delete

int main() {
    int n; cin >> n;
    int* arr = new int[n];      // 分配並預設初始化(int 不初始化)
    // int* arr = new int[n]();  // 值初始化為 0

    for (int i = 0; i < n; ++i) arr[i] = i;
    for (int i = 0; i < n; ++i) cout << arr[i] << ',';
    cout << endl;

    delete[] arr;  // 陣列必須用 delete[],單一物件用 delete
}

關鍵點

  • new T[n]:分配記憶體 → 呼叫每個元素的**建構子**(依序)。
  • delete[] ptr:呼叫每個元素的**解構子**(逆序) → 釋放記憶體。
  • 單一物件:new T / delete ptr。
  • 分配失敗拋出 std::bad_alloc(可用 new (std::nothrow) T 返回 nullptr)。
  • 不需頭檔,關鍵字內建。

核心差異對比表

特性malloc/freenew/delete
建構子/解構子不呼叫自動呼叫
類型安全void* 需強轉返回精確類型指標
失敗處理返回 nullptr拋出 bad_alloc
重載/自訂不可可重載 operator new/delete
陣列處理手動計算大小new T[n] / delete[] 自動管理
適用場景C 代碼、POD、與 C API 互操作C++ 類別物件、RAII、現代代碼

進階:placement new 與 記憶體池

// 在預先分配的緩衝區上建構物件
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass(args);  // 不分配記憶體,只呼叫建構子
obj->~MyClass();  // 手動呼叫解構子,不釋放 buffer

用於高效能記憶體池、共享記憶體、嵌入式系統固定記憶體佈局。

現代 C++:智慧指標與容器替代裸 new/delete

  • std::unique_ptr<T[]>:獨佔陣列,自動 delete[]。
  • std::shared_ptr<T>:共享擁有,控制區塊管理計數。
  • std::vector<T>:動態陣列,自動擴容、縮減、記憶體管理。
  • std::make_unique/make_shared:單一分配優化、異常安全。

常見錯誤與避坑指南

錯誤後果正確做法
delete arr; (陣列用 delete)未定義行為(通常只析構首元素,記憶體洩漏/崩潰)delete[] arr;
free(ptr) (new 分配)未定義行為配對使用:new↔delete, malloc↔free
重複釋放堆損壞、崩潰智慧指標、置 nullptr、RAII
使用已釋放記憶體未定義行為、安全漏洞釋放後置 nullptr、作用域限制
類別物件用 malloc建構子未執行,成員未初始化用 new 或 placement new

總結

堆記憶體管理是 C++ 核心技能。**現代 C++ 原則:盡量不直接呼叫 new/delete,改用標準容器與智慧指標**。必須手動管理時,嚴格遵循配對原則、區分陣列/單一物件、理解建構/解構語義,並建立 RAII 包裝器封裝裸指標。

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