我对以下代码感到有些困惑
void foo() {
std::list<A*> list;
for (int i = 0; i < 3; i ++) {
A a = A(i);
list.push_back(&a);
}
for (Iterator it = list.begin(); it != list.end(); it++) {
std::cout << (*it);
}
}
使用构造函数参数2打印出对象a的三倍,即在循环中构造的最后一个对象。
我在这里做错了什么?
答案 0 :(得分:4)
你有一个悬空指针列表。
for (int i = 0; i < 3; i ++) {
A a = A(i);
list(&a);
}
在每次迭代中,此循环创建一个A
类型的对象,当迭代完成时会立即销毁该对象。所以列表的内容是未定义的。你需要这样的东西:
for (int i = 0; i < 3; i ++) {
A* a = new A(i);
list(a);
}
...但是当你完成列表时,不要忘记将它们全部删除。
答案 1 :(得分:3)
变量a
是第一个for循环的局部变量,因此它在循环的每次迭代结束时被销毁。这意味着在循环结束后,list
中的所有三个指针都指向不再存在的对象。取消引用这些指针会导致未定义的行为。
答案 2 :(得分:0)
如果您不想再记住取消分配已分配的内存(并且代码更容易出错),则应使用unique_ptr
或shared_ptr
(请阅读相关内容)并尽可能地满足您的需求。
这是一个小例子(注意当向量超出范围时,向量中的元素如何被删除):
cout<<"Scope begins"<<endl;
{
vector< unique_ptr<A> > v;
for (int i=0; i<5; ++i){
v.push_back(unique_ptr<A>(new A(i)) );
}
}
cout<<"Scope ends"<<endl;
现场演示here。