mardi 3 janvier 2017

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) 3 smart pointers reside in 2nd vector. 3) the program starts to crash after several successful run.

  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?

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";}
    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& operator=(const A& rhs){
        cout << "A copy assignment\n";
        A temp(rhs); 
        swap(temp);
       return *this;
    }
    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;
    }
}

Aucun commentaire:

Enregistrer un commentaire