-4
#include <bits/stdc++.h>
using namespace std;

int main() 
{
    vector<int>p;
    p.push_back(30);
    p.push_back(60);
    p.push_back(20);

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i]<<" ";
}

The above code throws error as it is understood that p.end() point to null pointer.

While this code below is running fine and output is 30 60. Can anyone explain this?

#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
int main() 
{
    vector<pair<int,int>>p;
    p.push_back(mp(30,2));
    p.push_back(mp(60,5));
    p.push_back(mp(20,7));

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i].first<<" ";
}

2 Answers2

3

From std::vector::erase :

The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferencable) cannot be used as a value for pos.

So your code is invalid in both cases and invokes undefined behaviour. This means anything can happen including crash, work, or whatever it wants.

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • My doubt is why the p.erase(p.end()) is not giving any error in case of vector of pairs and erasing the last element?? – vikas choudhary Jul 04 '18 at 12:13
  • 1
    @vikaschoudhary Because the behaviour is *undefined*. Just like `int a[4]; a[6] = 10` is undefined. This might work, or fail, or crash or anything. It is not worth discussing what undefined behaviour might or might not do. – Fantastic Mr Fox Jul 04 '18 at 12:14
1

The above code throws error as it is understood that ...

That code is not guaranteed to "throw an error". Rather, the behaviour is undefined. Throwing an error is one possible behaviour. If it does throw an error, you can count yourself lucky as it might have been difficult to find your bug otherwise.

... as it is understood that p.end() point to null pointer.

No, p.end() does not "point to a null pointer". It points to the end of the vector, where end of the vector is defined as the position after the last element.

While this code below is running fine and output is 30 60. Can anyone explain this?

"Running fine" and "output is 30 60" are possible behaviours when behaviour is undefined. Everything is a possible behaviour when it is undefined. But of course, there is no guarantee that it will run fine. As far as the language is concerned, the program could just as well not be running fine tomorrow.

I have checked it on many online compilers but the output is same!!

Ouput being the same on many online compilers is also possible behaviour when behaviour is undefined. There is no guarantee that some compiler would behave differently, just as much as there is no guarantee for them behaving the same.

No matter how many compilers you try, it is impossible to verify that a program is correct simply by executing it and observing the output that you hoped for. The only way to prove a program correct, is to verify all pre-conditions and invariants imposed on the program are satisfied.

eerorika
  • 232,697
  • 12
  • 197
  • 326