【发布时间】:2018-10-14 23:52:00
【问题描述】:
我一直在研究动态分配,在 StackOverflow 上遇到了这个问题:
Deallocating objects stored in a vector?
其中一个被赞成的答案解释了如何在使用“指向对象的向量”时手动管理内存:遍历调用 delete 的向量。
我的问题是关于如何删除向量的特定元素,而不是整个向量。在下面的示例程序中,我有一个对象指针向量。想象一下,这些对象的 x 变量随着时间的推移而递减......当一个对象的 x 值达到一个数字(比如说 3)时,我希望删除该对象;但是,我想始终按对象的 x 值保持向量排序。
问题是当我对 x 值达到 3 的对象调用 delete 时,该对象被删除,但那里仍然有一个指向随机内存位置的指针,并且向量的大小也保持不变。
当我遍历打印 x 值的向量时,我调用删除的元素仍然存在,但指向像 -53408995 这样的值。如何摆脱向量的指针元素以及对象?
调用擦除不是一个选项,因为在我的实际程序(不是下面的最小示例)中,向量不断地由改变 x 值等价物的其他因素进行排序。我无法跟踪他们的索引。当我遍历向量以检查 x 值时,我想删除对象和指针元素。
例子:
#include <iostream>
#include <vector>
class A
{
public:
A(int i) { x = i; }
int x;
};
int main()
{
std::vector<A*> Vec;
Vec.push_back(new A{ 5 });
Vec.push_back(new A{ 4 });
Vec.push_back(new A{ 3 });
std::cout << "Size before = " << Vec.size() << std::endl; // 3
for (auto& a : Vec)
{
std::cout << a->x << std::endl;
if (a->x == 3) { delete a; }
}
std::cout << "Size after = " << Vec.size() << std::endl; // Still 3!
for (auto& a : Vec)
{
std::cout << a->x << std::endl; // Prints 5, 4 and a random memory location like -34528374
}
return 0;
}
【问题讨论】:
-
更改:
std::vector<A*> Vec;到std::vector<std::unique_ptr<A>> Vec;工作完成。或者问问自己为什么不只是std::vector<A> Vec; -
嗯,差不多完成了;用
std::make_unique<A>替换所有new A会更好 -
该向量还应该包含指向 A 的派生类的指针。对象还需要在各种其他向量/映射中具有指向它们的指针。
-
在这种情况下,正确的选择是使用 std::list
-
@NathanielG.M.
remove_if从向量中输入unique_ptr会破坏它指向的对象。remove_if从向量中调用shared_ptr会破坏该对象,如果它是指向该对象的最后一个shared_ptr
标签: c++ pointers vector memory-management dynamic-allocation