2013-12-13 30 views
0

當一個異常被拋出,然後在那裏它被拋出塊被從棧unwinded:例外,堆棧展開,包封的堆內存,出口()

int main() 
{ 
    try 
    { 
     Object x; // doesn't throw 
     Object y; // throws 
     cout << "wonderful"; 
    } 
    catch (...) 
    { 
     cout << "fail"; 
    } 
} 

Object分配上建設存儲器上堆和解除分配它正確地銷燬,那麼就應該是沒有內存泄漏,因爲棧展開的調用析構函數x(不y,但Object保證,當構造失敗,那麼沒有內存泄漏)。到目前爲止,不是嗎?

讓我們進入深度:

int main() 
{ 
    Object x; // doesn't throw 
    double *d = new double[256*256*256]; // doesn't throw 
    Object y; // throws 
    cout << "wonderful"; 
    delete[] d; 
} 

因爲良好的教育,我想自己清理垃圾我起來,不能讓這樣做的OS。我知道,每個現代操作系統本身都會刪除一個終止意外(或預期的,但沒有明確的重新分配)的程序的堆內存。因此,在上情況下,d的釋放會做我的操作系統,但x將仍能正常重新分配內存(因爲棧展開和析構函數調用) OS會做到這一點,對不對?

關於什麼:

#include <cstdlib> 

int main() 
{ 
    Object x; // doesn't throw 
    try { Object y; } // throws 
    catch (...) { cout << "fail"; exit(EXIT_FAILURE); } 
    cout << "working and working..."; 
    cin.get(); 
} 

x析構函數之前調用exit控制權給操作系統?

而且更深入:

void Object::be_stupid() 
{ 
    Object a; // doesn't throw 
    try { Object b; }// throws 
    catch (...) { exit(EXIT_FAILURE); } 
} 

void main() 
{ 
    Object x; // doesn't throw 
    try { x.be_stupid(); } // exits program 
} 

x構造稱爲exit控制權給操作系統過嗎?如果是,那麼exit「展開」所有周圍的堆棧,包括main(),對吧?

+1

出口不放鬆像異常拋出一樣。但是當你的程序即將死去時,你真的不需要這麼做。其他「立即死亡」功能也是如此,例如std :: terminate。 – polkadotcadaver

+0

@polkadotcadaver:當操作系統清理資源時,可能仍然需要銷燬對象,例如爲了獲得緩衝的流清理。然而'exit()'確實不會進行任何本地清理(它仍然會清理全局對象)。 –

+0

@DietmarKühl我同意 - 總是更好地處理優雅清理,特別是在RAII比新/刪除更有想象力的情況下使用。 – polkadotcadaver

回答

0

好,我知道感謝polkadotcadaver:從不使用exit(),傳播異常,直到main()並在那裏做一個簡單的return - 所有的堆棧Objects將自己的析構函數被釋放之前 OS取得控制權。