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

C++ 對象模型:new/delete 運算符深度解析

     編輯:關於C++

new 運算符的兩步語義

int *pi = new int(5); 實際分解為:

  1. 調用 `operator new(sizeof(int))` 分配原始內存(底層通常呼叫 `malloc`)。
  2. 在分配的內存上構造對象:`*pi = 5;`(對於類類型調用構造函數)。

編譯器生成類似:

int *pi;
if (pi = (int*)operator new(sizeof(int))) *pi = 5;

delete 運算符的保護語義

delete pi; 要求對空指針無操作,編譯器生成:

if (pi != 0) operator delete(pi);

注意:`delete` 後指針值不自動置零,後續使用屬於未定義行為。

類對象的 new/delete

Point3d *p = new Point3d;
// 轉換為:
Point3d *p;
if (p = (Point3d*)operator new(sizeof(Point3d)))
    p->Point3d::Point3d(); // 調用構造函數

異常安全:構造拋出異常時,編譯器會調用 `operator delete` 釋放內存。

標準庫 operator new 實現要點

void* operator new(size_t size) {
    if (size == 0) size = 1; // 保證返回唯一指針
    void* p;
    while (!(p = malloc(size))) {
        if (new_handler) (*new_handler)();
        else return 0; // 或拋 bad_alloc
    }
    return p;
}
void operator delete(void* p) {
    if (p) free(p);
}

數組 new 的特殊語義

  • new T[n]:若 T 為 POD 類型(無構造/析構),僅調用 `operator new[](n*sizeof(T))`。
     若 T 有構造函數,調用內部 `vec_new` 循環構造每個元素,並記錄元素個數(cookie 或關聯表)供 `delete[]` 使用。
  • delete[] p 必須匹配 new[],否則僅析構第一個元素導致內存洩漏。

Cookie 與關聯表

  • Cookie:在分配塊頭部額外存一個 `size_t` 記錄元素數。風險:壞指針導致讀取錯誤 cookie,析構次數錯誤。
  • 關聯表(如 Sun 編譯器):維護全局表映射指針→(大小, 析構函數),壞指針僅導致查表失敗,相對安全。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved