我正在编写一些代码,其中有2个向量分别包含4个智能指针。我不小心将第一个向量中生成的迭代器应用于第二个向量中的擦除方法。然后程序崩溃了。我了解到复制构造和移动构造涉及擦除方法。根据调试器,我发现1)nullptr和2个智能指针保留在第一个向量中。 2)4个智能指针驻留在第2个向量中。 3)程序在几次成功运行后开始崩溃。我的问题如下,
#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;
}
}
答案 0 :(得分:1)
在VS2015中,它在行vect2.erase(it);
上失败并显示消息; 迭代器越界确实是这样。
正如您在问题中所述it
甚至不属于vect2
。
即使它适用于您的平台,它也是未定义的行为。所以从那以后就会发生任何事情。
你不再使用c ++标准了,你现在正在处理你的平台实现的任何方式(也许它使用迭代器的指针,也许它使用偏移;谁知道?)。