1

Running the code below, I would expect to see a different address for the 4th value of test 1 (not the same as values 1 and 3). This shows that rend() is the same as rbegin() ?? I also would not expect the loop to go through a second iteration and get a segfault.

Any idea what I am doing wrong?

map<unsigned long, int*> newMap;
newMap[13] = new int(1340);
cout << "test 1:" << endl;
cout << &(*(newMap.begin())) << endl;
cout << &(*(newMap.end())) << endl;
cout << &(*(newMap.rbegin())) << endl;
cout << &(*(newMap.rend())) << endl;
cout << "test 2:" << endl;
for(map<unsigned long, int*>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){
  cout << "next iteration" << endl;
  map<unsigned long, int*>::reverse_iterator entry = it;
  it++;
  delete entry->second;
  newMap.erase(entry->first);
}

Output:

test 1:
0x2299050
0x7fffcd574908
0x2299050
0x2299050
test 2:
next iteration
next iteration
*** glibc detected *** ./foo: double free or corruption (fasttop): 0x0000000002299030 ***

EDIT: Here's an updated/simplified version, still with the same problem (test 2 only); this doesn't cause a segfault because it's not using pointers, but still goes through the loop twice:

map<int, int> newMap;
newMap[13] = 1340;
cout << "test 2:" << endl;
for(map<int, int>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){
  cout << "next iteration" << endl;
  int index = it->first;
  int value = it->second;
  it++;
  newMap.erase(index);
}
3pitom3
  • 11
  • 3

1 Answers1

0

In test 1, you are dereferencing the past-the-end iterators. As mentioned by ArchbishopOfBanterbury in the comments, the results of this are undefined.

In test 2, you are invalidating it by erasing the element pointed to by it.base(). std::reverse_iterator holds an iterator to the next element (so newMap.rbegin() holds an iterator equal to newMap.end() and newMap.rend() holds an iterator equal to newMap.begin()).

When you increment it, it becomes equal to newMap.rend(), meaning that it.base() is equal to newMap.begin(). You then erase the element referenced by it.base(), which invalidates it.base() thereby invalidating it as well. Since it is now invalid, comparing it to newMap.rend() doesn't work.

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52