2012-04-19 63 views
3

我試圖找出是否需要在下面的代碼的嘗試捕捉:任何C++ 98標準容器操作都可以拋出std :: bad_alloc嗎?

std::vector<int> values; 
// ignore that this can throw std::bad_alloc 
values.push_back(1); 
try { 
    for (std::vector<int>::iterator iter = values.begin(); 
     iter != values.end(); ++iter) { 
     ++(*iter); 
    } 
} catch (const std::bad_alloc&) { 
    // Is this needed? 
} 

通過C++ 1998標準看我能找到的唯一的事這暗示着這是一款23.1「集裝箱要求」子彈包含以下句子的點8:

此參數的副本用於在每個容器對象的生命週期內由這些構造函數和所有成員函數執行的任何內存分配。

我對此的解釋是,在一個容器中的任何成員函數可以調用分配,因此任何成員函數可以拋出的std :: bad_alloc的。我是過度偏執狂還是真的如此?

+1

由於編譯器限制,您是否正在查看98標準?因爲現在是03,現在是11. – GManNickG 2012-04-19 11:56:46

+0

@GManNickG - 是的,這是由於我針對的平臺受支持的編譯器的限制。 – 2012-04-20 07:22:02

回答

4

如果您進行進一步的閱讀了一下,你會發現23.1/10,這使集裝箱的有關異常時,可以拋出,特別要求:

  • 沒有erase()pop_back()pop_front()功能拋出異常。
  • 沒有拷貝構造函數或返回的迭代器的賦值操作符拋出異常。

如果你是真正的偏執狂,那麼你應該考慮的begin()end(),甚至是迭代增量,投擲方法可行;但沒有必要讓他們在標準容器的任何理智的實現中做任何複雜的事情。

2

Theorotically是的,任何標準庫容器成員函數都可以拋出bad_alloc

大多數標準容器本身不會拋出除(std::vector::at())之外的任何異常,但它們可以拋出內存分配失敗或用戶定義操作異常的異常。

我假設你的恐懼是push_back()在你的例子中拋出,如果不是,那麼你是偏執狂。儘管如此,這是一個實現細節在實踐中,如果您只是獲取迭代器,幾乎沒有實現會嘗試分配(begin()end())。

+0

我很高興'push_back()'可以拋出,我期望對任何一個容器的理性實現。我想知道其他容器方法調用可能拋出什麼,看起來大部分包括訪問條目都可能拋出。 – 2012-04-20 07:23:48

+0

@FreeWildebeest:技術上,是的。實際上,編號爲 – 2012-04-20 07:28:06

+0

我曾經'container.resize(var1 * var2)''var2'未初始化(和大)。結果是bad_alloc – Michael 2012-04-20 09:49:32

0

我沒有在標準中找到更具體的東西,所以在沒有證據的情況下,我們必須得出結論,技術上任何容器方法都可以拋出bad_alloc

我不擔心beginend儘可能地拋出容器本身,但還有另一個麻煩的地方:迭代器的實現。如果迭代器是類類型的,那麼在理論上這種實例的構造(或賦值)就可能拋出。所以雖然我不認爲任何隨機選擇的標準庫實現可能會拋出,但是你不能真正排除它。

相關問題