I have a class with a deque of strings and an iterator as members.
There's a GetNext()
method that gives me the next element and increments the iterator. Using the class from outside I check for an empty string to indicate the end of the deque.
Unfortunately I get a Heap corruption when the constructor is called and the last element was gotten using GetNext.
I suppose this happens because after the last string (empty string) in the deque, the iterator is still incremented and points somewhere in memory?
So that the destructor then tries to free this memory and then crashes?
#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;
}
}
Here's an example: Compilable and executable Example
You would need to check if pNextItem
is equal to list.cend()
before dereferencing. This is exactly what happens after the third call of foo.GetNext()
when you will dereference the last element and increment the iterator.
From deque::end
reference:
Returns an iterator to the element following the last element of the container.
This element acts as a placeholder; attempting to access it results in undefined behavior.