删除指针向量时出现问题
Having trouble deleting vector of pointers
我有一个管理器类,它持有指向虚拟基类的指针向量,以允许在那里存储各种子类。在这个管理器类的析构函数中,我希望它循环遍历它持有的所有指针并删除它们。然而,我已经尝试了许多遇到的方法,程序在执行过程中不断崩溃。
我的当前代码如下所示:-
for (std::vector<GameState*>::iterator it = gamestates_.begin(); it != gamestates_.end(); ++it){
delete *it;
it = gamestates_.erase(it);
}
有一件事我还没有尝试过,那就是使用unique_ptr,但我相信这应该能够在不使用它们的情况下处理它。如果我错了,请纠正我。
编辑:我知道我应该在循环后清除向量,但这是我在尝试了所有删除指针的正常方法后得到的结果。它似乎不喜欢delete命令。
从向量中删除元素会使迭代器无效,因此之后无法继续迭代。在这种情况下,我不会擦除循环中的元素;之后我会清除矢量:
for (auto it = gamestates_.begin(); it != gamestates_.end(); ++it){
delete *it;
}
gamestates_.clear();
虽然,如果它在析构函数中,并且向量即将被销毁,那么清除它也没有意义。
如果您确实需要在循环中擦除(可能是因为您只想擦除一些元素),那么您需要更加小心地保持迭代器的有效性:
for (auto it = gamestates_.begin(); it != gamestates_.end();){ // No ++ here
if (should_erase(it)) {
it = gamestates_.erase(it);
} else {
++it;
}
}
有一件事我还没有尝试过,那就是使用
unique_ptr
,但我相信这应该能够在不使用它们的情况下处理它。如果我错了,请纠正我。
如果你真的想通过steam来管理动态对象,那么请确保遵循三条规则:你需要实现(或删除)复制构造函数和复制赋值运算符,以防止"浅层"复制给你留下两个试图删除相同对象的向量。您还需要注意在任何其他位置删除或替换对象。存储智能指针(或者对象本身,如果你不需要多态性指针的话)会为你处理所有这些事情,所以我总是建议你这样做。
我知道我应该在循环后清除向量,但这是我在尝试了所有删除指针的普通方法后得到的结果。它似乎不喜欢delete命令。
最有可能的原因是您没有遵循"三条规则",并且在复制向量后意外地尝试删除相同的对象两次。也有可能GameState
是一个基类,而您忘记给它一个虚拟析构函数,或者指针已被其他代码损坏。
您的迭代器在每个循环中更新两次:
it = gamestates_.erase(it);
和
it++
您只需要第一个——它已经指向容器中的"下一个对象"。
从向量中删除元素将使迭代器无效。删除对象指针中的元素,然后clear()
向量的内容。
去掉for
循环头中的++it
。
erase
已经为您预付了。
或者,迭代、删除,然后在迭代.clear()
之后。
更喜欢使用unique_ptr
。你说你应该能够在不使用它们的情况下处理它,就好像让一个智能指针为你做这项工作是一种可怕的强加。
他们在那里是为了让你的生活更轻松,你不必因为没有亲手做艰苦的工作而感到内疚。
使用现有的代码,不要调用erase
。矢量无论如何都会被摧毁,对吧?这一切都会自己解决的。
问题是it
增加了两次。首先,当您调用返回下一个元素的it = .erase(it)
时,然后在循环中调用++i
。你可能会不经意地跳过终点,事情可能会出错,更不用说你只会删除向量的每一个元素。
一个简单的解决方案是不更改循环中的it
(无++it
)。
更好的方法是从向量的末尾实际删除数组,因为从向量内部擦除元素会导致所有后续元素的昂贵移动。您当前的算法将在N^2
时间内工作。试试这样的东西:
while (!gamestates_.empty()) {
delete gamestates_.back();
gamestates_.erase(gamestates_.end()-1);
}
您也可以迭代向量的所有元素,然后清除它:
for (std::vector<GameState*>::iterator it = gamestates_.begin(); it != gamestates_.end(); ++it){
delete *it;
}
gamestates_.clear();
还要注意,向量的clear()
运算也在其析构函数中完成。如果删除过程是某些销毁过程的一部分,其中gamestates_
被完全销毁,那么您根本不必调用clear()
。
- 关于 c++ 函数中指针赋值的简单问题
- 链表指针问题
- C++ 关于指针取消引用的技术问题
- C++中的指针和常量问题不大
- 包含矢量指针的结构的内存释放问题
- 指针问题:从不兼容的类型"int"分配给"int *"
- 将字节数组转换为带有字节序问题的指针
- 关于如何使用指向主窗口的指针的 QT 问题
- 当成员值从指针更改为非指针时,C++常量问题
- 为什么循环会导致指针出现问题?
- 使用指针计算堆栈问题的大 O 表示法
- 构造函数 (C++) 中的 char 指针参数存在问题
- 指向包含对齐 C 结构C++类的 C 指针的对齐问题
- 涉及指针和手动实现的矩阵类的问题
- 从基指针到派生的强制转换问题
- 迭代器的指针操作问题
- 64 位迁移问题:指针更改
- C++模板使用问题指针
- 跳到C++第13章练习问题4-指针
- 用std::pair数组初始化std::map问题(指针错误?)