0

I have come across this post on stack overflow and found out the way to delete elements in a list iteratively. I wanted to try the same with both map and list. I got a segmentation fault with list as expected but I did not get one with map. Why is it so??

Below are the codes for both.

Using list :

#include <iostream>
#include <list>
using namespace std;
int main()
{
   list<int>l ;
   l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);
   list<int>::iterator it;
   for(it = l.begin();it!=l.end();it++){
       l.erase(it);
       cout<<"Give me some output..\n";
   }
   return 0;
}

Output :

Give me some output..
Segmentation fault (core dumped)

Using map :

#include <iostream>
#include <map>
using namespace std;
int main()
{
   map<int, int>m ;
   m[1] = 1;m[2] = 2;m[3] = 3;m[4] = 4;
   map<int,int>::iterator it;
   for(it = m.begin();it!=m.end();it++){
       m.erase(it);
       cout<<"Give me some output..\n";
   }
   return 0;
}

Output :

Give me some output..
Give me some output..
Give me some output..
Give me some output..

Shouldn't list iterators and map iterators show the same behaviour ??

ASIDE :

The actual problem I was facing was I was using a map in a big program and trying to delete elements from it with the wrong method mentioned above and I got the segmentation fault. Then I visited the above mentioned link and resolved the issue.But shouldn't both the codes give segmentation fault. How can two codes using same snippet of code show different behaviours. Is it that one code is small, hence the compiler was able to correct that by itself??

Community
  • 1
  • 1
2rd_7
  • 462
  • 1
  • 3
  • 15
  • 10
    Lack of segmentation fault is one of the possible observable effects of undefined behavior. Your question is like 'Laws say that theft is punishable with prison, but I just stole something an no one caught me. But my friend stole something else and she got caught and now she is serving time. How so?' – SergeyA Jun 14 '16 at 20:59
  • So, it means that we can get an output for `cout< 0. Am I correct?? – 2rd_7 Jun 14 '16 at 21:05
  • 1
    @2rd_7 it can do anything (literally) see: http://www.catb.org/jargon/html/N/nasal-demons.html – Richard Critten Jun 14 '16 at 21:07
  • I doubt there is any event in the universe for which you can say that it's probability is 0. – SergeyA Jun 14 '16 at 21:08
  • 2
    @SergeyA There is probability 0 that I have 17 fingers. – Barry Jun 14 '16 at 21:11
  • It simply means that the C++ standard does not prescribe the behavior. The behavior is determined by other factors related to your particular implementation. – Benjamin Lindley Jun 14 '16 at 21:12
  • @Barry, this is not a question of probability theory for you. It is already a fact. You do have a certain number of fingers. However, the probability that someone I meet today has 17 fingers is not 0. (Even that for that person it is also not a probability, but a fact!) Probability theory is fun and paradoxical like that. – SergeyA Jun 14 '16 at 21:16
  • But think of how fast Barry could code with 17 fingers. That would be awesome! – user4581301 Jun 14 '16 at 23:43

1 Answers1

2

Both list::erase and map::erase state:

References and iterators to the erased elements are invalidated. Other references and iterators are not affected.

When you subsequently call it++ you are incrementing an invalid reference is Undefined Behavior.

Fortunately this is a simple problem to solve as both containers' erase-methods return the next valid iterator, so if for some reason you didn't just want to call clear you could do:

for(auto it = cbegin(l); it != cend(l); it = l.erase(it)) cout << "Give me some output..\n";
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288