William
William

Reputation: 63

Erase Method in Vector

I'm writing some codes in which there are 2 vectors containing 4 smart pointers respectively. I accidentally apply an iterator generated in the first vector to the erase method in the second vector. Then the program crashes. I learn that the copy construction and the move construction get involved the erase method. In light of the debugger, I figure out 1) a nullptr and 2 smart pointers stay in 1st vector. 2) 4 smart pointers reside in 2nd vector. 3) the program starts to crash after several successful run. My questions are as follows,

  1. how is the nullptr appended to 1st vector?
  2. Why is it permissible to apply the iterator to 2nd vector?
  3. Why does the program not crash from the outset?

BTW, my platform is Xcode 8.1. Thanks in advance

#include <memory>
#include <vector>
#include <iostream>
#include <string>

using namespace std;

class A{
public:
    A(string name_) : name(name_) {cout << name << " construction\n";}
    const string& get_name() const {return name;}
    ~A() {cout <<get_name() << " destruction\n";}
    A (const A& rhs) : name(rhs.name){cout << "A copy constructor\n";}
    A(A&& rhs) : name(""){
        cout <<"A move constructor\n";
        swap(rhs);
    }
    void swap(A& rhs) noexcept {
        std::swap(name, rhs.name);
    }

private:
    string name;
};
void foo();

int main(){
    foo();
}

void foo(){
    vector<shared_ptr<A>> vect1, vect2;
    auto a1 = make_shared<A>("Mike");
    auto a2 = make_shared<A>("Alice");
    auto a3 = make_shared<A>("Peter");
    auto a4 = make_shared<A>("Paul");
    vect1.push_back(a1);
    vect1.push_back(a2);
    vect1.push_back(a3);
    vect1.push_back(a4);
    vect2.push_back(a4);
    vect2.push_back(a1);
    vect2.push_back(a2);
    vect2.push_back(a3);
    auto it = vect1.begin();
    vect1.erase(it);
    for (auto &c : vect1){
        cout << c->get_name() << endl;
    }
    vect2.erase(it);
    for (auto &c : vect2){
        cout << c->get_name() << endl;
    }
}

Upvotes: 0

Views: 69

Answers (1)

wally
wally

Reputation: 11002

In VS2015 it fails on line vect2.erase(it); with the message; Iterator out of bounds which indeed it is.

As you state in the question it doesn't even belong to vect2.

Even if it works on your platform it is undefined behavior. So from then on anything can happen.

You're not working within the c++ standard anymore, you're now dealing with whichever way your platform was implemented (maybe it uses pointers for iterators, maybe it uses offsets; who knows?).

Upvotes: 1

Related Questions