C++98/C++03 STL set bug?

-1

all,

One weird thing happens when I'm using set: Let's say:

struct A {
  int num;
  bool operator<(const A& x) const
  {
    return num < x.num;
  }
};

struct B {
  set<A> ASet;
};

struct C {
  list<B> BList;
  list<B>::iterator BListIter;
  C()
  {
    BList.push_back(B());
    BListIter = --(BList.end());
  }
};

somewhere we can have this code:

list<C> CList;
CList.push_back(C());
list<C>::iterator CListIter = --(CList.end());
for (...) {
  A a = ...;
  ...
  CListIter->BListIter->ASet.insert(a);

this will end up with segmentation fault after a few iterations. When this happens, I found an invalid item is referenced and compared (its address is 0x0000001b, so definitely wrong) during the insertion.

Funny thing is when I turn on -std=c++0x this option to use C++11 the problem goes aways! So I wonder if this is a bug of STL set in C++98/C++03?

Thanks,

Kevin

c++
stl
set
asked on Stack Overflow Feb 5, 2014 by user3277360

1 Answer

2

In C++03 or earlier, copies of the temporary objects are put on CList and the BList inside the CList object.

When the C::BList member is copied, a completely new list<B> is created, but when the C::BListIter member is copied, the new C::BListIter iterator still refers to the C::BList list in the original C object - which is a temporary that gets destroyed. So that iterator refers to an element of a destroyed list.

In C++11 move constructors are used instead of copy constructors, so the resulting iterator doesn't refer to a dead object.

answered on Stack Overflow Feb 6, 2014 by Michael Burr

User contributions licensed under CC BY-SA 3.0