2014-12-02 25 views
3

最近一位面試官問我C++中的異常對象在哪裏被分配,堆或棧?我不確定,但我回答了堆棧,因爲我認爲沒有「新」或「malloc」。這是對的嗎?異常對象在哪裏有它的空間,堆或棧,以及如何在不同的類中訪問它?

然後他一直問我,是否在堆棧上,假設類A拋出一個異常對象,讓我們說「e」,並且類B抓住「e」。由於「e」在A堆棧中,那麼B如何訪問這個「e」?

我不是很清楚第二個問題。任何人都可以給我一些示例代碼,顯示「A類拋出E和B類捕獲它」?另外,我猜測B可以通過複製值或地址來捕獲e,但是面試者只是拒絕我的答案而沒有給我一個正確的答案,那麼什麼是正確的答案,有沒有什麼機制可以確保類對象可以從其他類對象中捕獲異常?感謝〜

+1

自己堆棧的類嗎?這聽起來像一個混亂的採訪者。堆棧用於實現功能,整個程序使用相同的功能;函數拋出異常,函數捕獲異常。 – molbdnilo 2014-12-02 21:55:26

+0

@molbdnilo - 一個程序可以有多個堆棧。這取決於選擇的編譯器和選項。通常,程序在其整個生命週期中使用相同的堆棧,但不是必需的。 – StarPilot 2014-12-02 22:01:44

+0

答案是**既不**。 – Deduplicator 2014-12-02 22:04:31

回答

7

從[except.throw] /15.1/4:

爲異常對象的存儲器被分配在未指定的方式,除非在3.7.4.1指出。

最終參考,[basic.stc.dynamic.allocation/4時,表示:

[:具體地講,一個全局分配功能不被調用用於分配存儲[ ...]一個異常對象(15.1)。 - 注完]

+1

註釋有點含糊(至少沒有更多上下文)。顯然,通常的堆棧分配機制不能分配一個異常,因此必須調用某種分配函數。 (但是答案的關鍵在於第一個引號,在我實際研究的實現中,所有的都使用自定義分配機制,因此異常既不在堆中,也不在堆棧中。) – 2014-12-03 00:08:48

+0

@JamesKanze:你是正確的,上下文(即與全球分配函數*的定義有關)將在這裏起作用。 – 2014-12-03 09:54:41

+0

是的。我提到它指的是§3.7中描述的全局分配函數 ,因爲這些函數不能用於例外,至少不是排他性的。但是,從上下文中,人們可以很容易地理解它是指全局可訪問的任何分配函數。 – 2014-12-03 13:43:54

0

「但我回答,因爲我覺得沒有 」新「 或 」malloc的「 是正確的。?」

基本上是的,儘管異常處理的情況比較特殊,因爲它解開的堆棧throw操作。

struct SomeException { 
}; 

void throwing_func() { 
     throw SomeException(); 
} 

int main() { 
    try { 
     throwing_func(); 
    } 
    catch(const SomeException& ex) { 
     std::cout << "Caught 'SomeException' exception" << std::endl; 
    } 
} 

void throwing_func() { 
     throw SomeException(); 
} 

的局部範圍是某種等同尋找一個local scope和匹配那種local scope與最佳匹配catch(...)聲明。

0

throw new std::exception vs throw std::exception

上面的鏈接有一個相當不錯的答案。

我認爲答案是「通常」堆,因爲你扔的物體將位於堆上,但如果它是一個靜態對象(不知道這樣的事情是否存在),那麼它會在棧上。

1

它不能像堆棧拋出異常時一樣堆棧,如果在引起異常的幀中分配了異常對象,就會丟失異常對象。

我記得在C++ Primer 5Ed中閱讀了一些關於它的東西。它說

異常對象駐留在空間,由編譯器管理,保證可以訪問任何捕獲被調用。異常完成後,異常對象被銷燬。

並且看着上面的@ Kerrek的asnwer,我相信它是一個單獨的空間分配,並且是編譯器特有的。

相關問題