2017-02-28 40 views
2

我有一個類的字符串和迭代器作爲成員。 有一個GetNext()方法,給我下一個元素並增加迭代器。使用來自外部的類我檢查一個空字符串以指示雙端隊列的結束。 不幸的是,當構造函數被調用並且最後一個元素使用GetNext時,我得到了一個Heap腐敗。 我想這是因爲在雙端隊列中的最後一個字符串(空字符串)之後,迭代器仍然遞增並在內存中指向? 這樣,析構函數然後試圖釋放這個內存,然後崩潰?使用const_iterator成員調用類的析構函數時發生堆損壞

#include <iostream> 
#include <string> 
#include <deque> 


class Foo 
{ 
public: 
    Foo() 
    { 
     list.push_back("first elm"); 
     list.push_back("second elm"); 
     list.push_back(std::string());  
     pNextItem = list.begin(); 
    } 

    virtual ~Foo(){} 

    const std::string& GetNext() { return *pNextItem++; } 

protected: 

    std::deque<std::string> list; 
    std::deque<std::string>::const_iterator pNextItem; 
}; 


int main() 
{ 
    { 
    Foo foo; 
    std::cout << foo.GetNext() << std::endl; // "first elm" 
    std::cout << foo.GetNext() << std::endl; // "second elm" 
    std::cout << foo.GetNext() << std::endl; // "" 
    //third call sets the iterator past the last element and causes a segfault 
    std::cout << foo.GetNext() << std::endl; 

    } 

} 

下面是一個例子: Compilable and executable Example

+0

我編輯了示例以包含用法和指向tutorialspoint.com上的可編譯代碼的鏈接 – tzippy

回答

3

您將需要檢查是否pNextItem是反引用之前等於list.cend()。這正是foo.GetNext()的第三次調用後發生的情況,當您取消引用最後一個元素並遞增迭代器時。

deque::endreference

返回 容器的最後一個元素之後的迭代器的元素。

此元素充當佔位符;試圖訪問它導致 未定義的行爲。

+0

我在使用該類的地方添加了代碼。 – tzippy

+0

@tzippy,所以我做了一個很好的猜測然後:)更新了答案。 – AMA

+0

很好猜對;)謝謝你的答案。這會是一個好方法嗎? : '常量的std :: string&的GetNext(){ \t如果(pNextItem == list.end()) \t \t回報* pNextItem; \t return * pNextItem ++; }' – tzippy

相關問題