2013-01-11 40 views
6

我使用googletest測試我的C++代碼。當拋出vector::_M_range_check例外,因爲一個std::vector與一個錯誤的指數,googletest報告訪問:Google測試和std ::向量範圍例外

C++ exception with description "vector::_M_range_check" thrown in the test body. 

太好了,現在我也想知道哪個載體,指標和範圍。我如何輕鬆獲得這些信息,並將測試代碼保存在googletest單元測試用例中?

(我幾乎開始漫長的Java憑藉其良好的老IndexOutOfBoundsException ...)

+0

--gtest_catch_exceptions = 0 – JaredC

+0

@JaredC此標誌在引發異常後終止測試,但輸出不會提供有關異常原點的信息(向量,索引,範圍) – clstaudt

+2

@cls:如果您運行在調試器中測試,或在終止後檢查覈心轉儲,然後您應該看到未處理的異常從何處拋出。或者,你可以在'std :: __ throw_out_of_range'上放置一個斷點,這是GNU庫調用來拋出異常的函數。 –

回答

8

如果您使用此命令行選項,那麼你的異常將泡沫一路跑得:

--gtest_catch_exceptions=0 

在調試器中執行此操作將爲您提供異常的確切堆棧跟蹤。

+0

正確,但不是索引和邊界作爲錯誤的原因。 – clstaudt

+3

@cls調試器停止後,該信息即可用。 – JaredC

6

谷歌測試並不這裏涉及。您的C++標準庫實現拋出一個異常,取決於您的C++標準庫實現,以決定如何詳細設置它的例外。

由於您收到一個例外,我假設您使用的是std::vector::at而不是std::vector::operator[]。有幾種可能的方法可以用來獲取更多信息。

首先,你可以使用到operator[]電話(個人而言,我不覺得at的異常投擲範圍檢查是非常有用的,它也有一個性能開銷)替代調用at和使用你的C++標準庫實現的迭代器調試。例如,G ++,如果我用operator[]-D_GLIBCXX_DEBUG編譯打開範圍檢查operator[],我得到類似如下的錯誤:

/usr/include/c++/4.3/debug/vector:237:error: attempt to subscript container 
    with out-of-bounds index 0, but container only holds 0 elements. 

其次,你可以通過調用test_at取代調用at或類似:(未經測試)

template <typename T> 
T& test_at(std::vector<T>& v, size_t n) { 
    // Use Google Test to display details on out of bounds. 
    // We can stream additional information here if we like. 
    EXPECT_LT(n, v.size()) << "for vector at address " << &v; 

    // Fall back to at, and let it throw its exception, so that our 
    // test will terminate as expected. 
    return v.at(n); 
} 
0

vector::at(size_type n)被記錄爲在無效的n(23.2.3p17)上投擲out_of_rangeout_of_range不攜帶容器或索引上的信息,所以你必須包裝at如果你想要的信息:

template<typename T> struct my_vector: public std::vector<T> { 
    using std::vector<T>; 
    struct at_out_of_range: public std::out_of_range { 
    my_vector *vector; 
    size_type size; 
    size_type n; 
    at_out_of_range(my_vector *vector, size_type size, size_type n): 
     std::out_of_range("at_out_of_range"), vector(vector), size(size), n(n) {} 
    }; 
    reference at(size_type n) { 
    try { 
     return std::vector<T>::at(n); 
    } catch(std::out_of_range &ex) { 
     std::throw_with_nested(at_out_of_range(this, size(), n)); 
    } 
    } 
}; 

注意at不是虛擬的,所以你必須通過包裹at調用來獲取嵌套異常。