2014-03-03 92 views
0

之後被釋放,我知道Object *pObject=new Object包含兩個步驟:如果分配的內存構造函數拋出異常

  1. 運營商新的分配內存
  2. 調用對象的構造函數。

,並呼籲delete pObject

  1. 調用對象的銷燬;
  2. 運算符刪除以釋放內存。

但是,當新的Object進程,如果第2步拋出異常,如果運算符刪除被系統調用來釋放內存?

+0

不要在構造函數中拋出異常。 –

+1

@EdHeal,爲什麼不呢?這似乎是構建對象時處理錯誤的常用方法之一,並且在正確編寫對象時不應該泄漏或任何內容。 – chris

+0

是的,調用'operator new'的相同格式的'operator delete'將被調用。 – songyuanyao

回答

1

不,不會調用析構函數。由於對象構造不當,因此調用析構函數是不安全的。但是,如果任何成員對象已經完全構建,那麼它們將被破壞(當對象完成時)。

有人建議不要扔在構造函數中,我相信它比殭屍狀態更好,它類似於錯誤代碼並製作冗長的代碼。只要你遵循RAII,你應該沒問題(每個資源都由它自己的對象來管理)。在你拋出構造函數之前,確保你清理了所有你已經完成的任何事情,但是,如果你使用的是RAII,那應該什麼也不是。

下輸出 「B」:

#include <iostream> 

struct B { 
    ~B() { std::cout << "B" << std::endl; } 
}; 

struct A { 
    A() : b() { throw(1); } 
    ~A() { std::cout << "A" << std::endl; } 
    B b; 
}; 

int main() { 
    try { 
    A *a = new A; 
    delete a; 
    } catch(int a) {} 
} 

編輯: 上面沒有你問,是delete操作符被調用,http://www.cplusplus.com/reference/new/operator%20delete []說:

「這些釋放函數由delete-expressions和new-expressions調用,以便在破壞(或未能構造)具有動態存儲持續時間的對象後釋放內存。

這可以通過覆蓋運營商delete來測試。

+0

我知道destruct不會被調用,但我現在不知道如果調用者被刪除,是否被調用。 – jiafu

+0

不會調用'delete',因爲'delete'調用析構函數。你混淆了'malloc' /'free'和'new' /'delete'。 – Cramer

+0

我的意思是操作員刪除不刪除指針的刪除。 – jiafu

0

是的,操作員刪除將被調用來釋放分配的內存。

下面的程序可以證明:

#include <iostream> 

using std::cout; 
using std::endl; 

class A { 
public: 
    A() { cout << "A() at " << this << endl; throw 1; } 
    ~A() { cout << "~A() at " << this << endl; } 
}; 

int main(int argc, char *argv[]) { 
    int N = 3; 
    for (int i = 0; i < N; ++i) { 
     try { 
      new A; 
     } catch (int a) { 
      // pass 
     } 
    } 
    return 0; 
} 

運行我的系統上這個節目,我發現結果打印出來是這樣的:

A() at 0x2170010 
A() at 0x2170010 
A() at 0x2170010 

顯然,析構函數不要撥打因爲沒有

~A() at 0x2170010 

行被打印出來。

而操作符刪除肯定會被調用,因爲三個對象的地址完全相同。

相關問題