2011-12-01 85 views
2

我的程序在這一行崩潰,但只在調試版本中,它在發佈版本中工作正常。C++ std :: vector.insert在調試時崩潰,但在發佈版本上工作

m_lstIds.insert(m_lstIds.begin() + indexInsert, ID); 

'm_lstIds'是int的std :: vector,'ID'是int。當程序崩潰時,m_lstIds有3個項目(1,2,3)。 indexInsert爲'0'且ID爲'0'。

錯誤消息說:

Expression: vector iterator + offset out of range 

我運行Visual Studio 2010;我猜測它與一些與STL優化相沖突的不良項目設置有關。

編輯: 當我說: 「上發佈的作品」 我的意思是,如果我對i = 0..3做std::cout<<m_lstIds[i],我會真正得到0,1,2,3打印出來。在調試版本中,當我嘗試插入時,它只是崩潰。

編輯2: 我找到了答案!感謝大家的幫助。

這裏是最短的repro。問題是我在構造函數處調用的memset函數。因爲m_lstItem的構造函數在memset之前被調用,所以它將擦除向量中允許insert正常工作的任何數據。

真正有趣的是這是如何在發行版中起作用,但在調試中不起作用。如果有人能解釋那部分,那將會很棒。

struct SimpleList 
{ 
    SimpleList() 
    { 
    memset(this, 0, sizeof(SimpleList)); 
    m_lstItem.push_back(0); 
    m_lstItem.push_back(1); 
    m_lstItem.push_back(2); 
    } 

    void Crash() 
    { 
    m_lstItem.insert(m_lstItem.begin() + 0, 3); 
    } 

    std::vector<int>m_lstItem; 
}; 

int main(int argc, char** argv[]) 
{ 
    SimpleList sl; 
    sl.Crash(); 
    return 0; 
} 
+3

你確定容器有三個元素,索引是0嗎?它在發行版中「起作用」的事實意味着代碼實際上已被破壞,但沒有運行時檢查,您不會收到任何錯誤。 –

+5

「Not crashing」!=「working」 –

+2

向我們展示您的代碼的工作示例,我們很難弄清楚向量如何修改,使用等。 – birryree

回答

4

memset(this, 0, sizeof(SimpleList));當你的結構是不是POD是不安全的。

由於會員std::vector<int>m_lstItem;,你的結構不是POD。

爲此,使用memset在這種情況下不安全,並導致未定義行爲。換句話說:任何事情都可以發生!而什麼包括按預期工作...

我的建議是:不要在C使用memset ++,除非你完全知道自己在做什麼。

+0

這沒有回答我的問題,但你的答案發布後,我發現自己的問題:-) – Twelvethousand

+0

@Twelvethousand它是在發佈完整代碼後發佈。任何專家在閱讀後都會在幾秒鐘內指出memset。 – Sjoerd

0

我猜索引運行時indexInsert不是0。 當矢量在DEBUG模式下超出範圍時,向量將拋出異常,而在RELEASE模式下它不會。 因此,向您展示完整的代碼。

+0

你是對的,不能memset結構其中包含STL變量;我犯了以前的錯誤,因爲你是:-) –

相關問題