使用const_iterator成员调用类的析构函数时堆损坏

时间:2017-02-28 10:47:25

标签: c++ heap-corruption

我有一个带有deque of strings和一个迭代器作为成员的类。 有一个GetNext()方法,它为我提供了下一个元素并递增了迭代器。使用外部的类我检查一个空字符串,以指示双端队列的结束。 不幸的是,当调用构造函数并使用GetNext获取最后一个元素时,我得到了Heap损坏。 我想这是因为在deque中的最后一个字符串(空字符串)之后,迭代器仍然会递增并在内存中指向某处? 那么析构函数然后尝试释放这个内存然后崩溃?

   #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

1 个答案:

答案 0 :(得分:3)

在解除引用之前,您需要检查pNextItem是否等于list.cend()。这正是在第三次调用foo.GetNext()之后发生的情况,当你取消引用最后一个元素并增加迭代器时。

来自deque::end reference

  

返回元素的最后一个元素后面的元素的迭代器   容器

     

此元素充当占位符;试图访问它导致   未定义的行为。