Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault on erasing the last element from the vector C++

Tags:

c++

stl

stdvector

I created a simple C++ program to test the behaviour of erase() in C++ vectors.

This is my code:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // your code goes here

    vector<int> vec;

    vec.push_back(3);
    vec.push_back(4);
    vec.push_back(5);

    cout << vec[0] << " " << vec[1] << " " << vec[2] << endl;

    vec.erase(vec.end());
    //vec.erase(vec.begin());

    cout << vec.size() << endl;

    vec.push_back(12);
    vec.push_back(10);

    cout << vec[0] << " " << vec[1] << " " << vec[2] << endl;


    return 0;
}

The problem is the above code is giving segmentation fault when trying to erase the last element from the vector. But when I erase the first element using begin(), it is working fine. I am unable to understand the reason behind it. Any help would be highly appreciated.

like image 332
Bhawan Avatar asked Feb 22 '18 07:02

Bhawan


3 Answers

The problem is that std::vector::end returns an iterator to the element following the last element of the container, not to the last element.

What you want should be

vec.erase(vec.end() - 1); // trying to erase the last element of vec
like image 153
songyuanyao Avatar answered Oct 23 '22 16:10

songyuanyao


vec.end() is giving you the iterator to the element following the last element of the container. See here:

enter image description here

Attempting to erase it is undefined behaviour. You should instead erase by doing either:

vec.erase(vec.end() - 1);

or better yet use pop back:

vec.pop_back();

 
like image 12
Fantastic Mr Fox Avatar answered Oct 23 '22 18:10

Fantastic Mr Fox


std::vector::end() returns an iterator that is one past the last element of the object. It is not valid for erasing. To remove the last element from a vector, you need to use the iterator that points to the last element.

You can use begin() + size - 1 for that.

size_t size = vec.size();
vec.erase(vec.begin() + size - 1);

Better yet, use std::vector::pop_back().

vec.pop_back();
like image 6
R Sahu Avatar answered Oct 23 '22 18:10

R Sahu