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

C++ 中 destroy、deallocate 與 delete 的關係與區別

     編輯:C++ 入門

C++ 中 destroy、deallocate 與 delete 的關係與區別

STL 分配器將對象銷毀分為兩步:析構 與 內存釋放,分別對應 destroy() 和 deallocate();而 delete 表達式一次性完成兩者。

三者對比

操作功能層級典型實現
destroy(p)調用對象析構函數,釋放對象內部資源分配器成員 / std::allocator_traitsp->~T()
deallocate(p, n)歸還原始內存塊給分配器/系統,不調用析構分配器成員::operator delete(p) 或內存池回收
delete p先析構,後釋放內存(單對象)語言運算符p->~T(); ::operator delete(p);
delete[] p逐個析構陣列元素,釋放整塊內存語言運算符循環析構 + ::operator delete(p)

代碼示範錯誤用法

struct A { char* buf; A() { buf = new char[1000000]; } ~A() { delete[] buf; } };
int main() {
    std::allocator alloc;
    for (;;) {
        A* p = new A;
        alloc.deallocate(p, 1); // 僅釋放 A 對象內存,未調用 ~A() → buf 洩漏
    }
}

正確做法:

alloc.destroy(p); // 調用 ~A() 釋放 buf
alloc.deallocate(p, 1); // 釋放 p 本身
// 或直接
delete p; // 編譯器自動生成上述兩步

STL 容器析構流程

// vector 析構簡化邏輯
~vector() {
    for (auto it = begin(); it != end(); ++it)
        alloc.destroy(&*it); // 1. 析構元素
    alloc.deallocate(data_, capacity()); // 2. 釋放緩衝區
}

關鍵區別

  • ::operator delete:全局釋放函數,僅釋放內存,不調用析構。
  • deallocate:分配器封裝,可能走內存池,不調用析構。
  • destroy:僅調用析構,不釋放內存。
  • delete:語言級運算符,原子性完成析構+釋放,不可分割。

最佳實踐

  • 使用標準容器/智能指針,極少手動調用 destroy/deallocate。
  • 自定義分配器時,必須成對調用 construct/destroy 和 allocate/deallocate。
  • 理解「析構 ≠ 釋放內存」是避免洩漏/雙重釋放的關鍵。

總結

destroy 負責「對象級清理」,deallocate 負責「內存級回收」,delete 將兩者綁定。STL 分配器分離二者以支持內存池、對象池等高級優化。應用層代碼應優先使用 delete、智能指針或容器,避免手動拆分導致錯誤。

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