2017-02-28 137 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