指针向量,其元素用new初始化:赋给新值时会发生什么



我有一个像这样的指针向量:

std::vector<foo*> stuff;

我用new foo();:

初始化每个元素

我的问题是,当我重新分配向量的一个元素时,会发生什么,比如

stuff[3] = new foo();

我是否泄漏内存,我是否应该在此之前调用delete[] ?这种情况下我应该使用智能指针吗?(从未有过)

通常我不会使用新的,但我正在学习Qt,这是如何在例子中完成的。Qt似乎有自己的智能指针;我应该用其中一个吗?

谢谢。

是的,当stuff被销毁时,您会泄漏所有那些动态分配的foo未被删除并且无法访问,除非您遍历向量并调用delete。

通常当你想要一个指针的向量时你使用std::shared_ptr

std::vector<std::shared_ptr<foo>> stuff;
stuff[3] = std::make_shared<foo>();

这可能是一个潜在的性能瓶颈,如果vector是巨大的,你试图复制它(然后可能你想包装它在另一个shared_ptr),但如果你只是访问vector的元素,它消除了所有的问题,关于谁删除什么,何时与原始指针方法。

我的问题是,当我重新分配向量的一个元素时,会发生什么,比如

stuff[3] = new foo();

我在泄漏内存吗

是的,你在泄漏内存。vector不知道谁负责拥有你分配的对象。它无法区分以下内容:

stuff[3] = new foo();

foo f;
stuff[3] = &f;

因此它不会为您做任何清理。

,我应该在此之前调用delete[]吗?

不完全是。delete[]用于销毁动态分配的数组;它是用来销毁通过new[]分配的东西的。要销毁通过普通new分配的东西,应该使用普通delete

这是我应该使用智能指针的情况吗?(从未有过)

是的。如果你使用std::shared_ptr<foo>(或boost::shared_ptr<foo>,如果你不能使用c++ 11),那么std::shared_ptr对象将为你负责delete对象。

我没有看到任何关系与Qt在你的代码。使用new分配对象后不调用delete会发生内存泄漏。你应该做的是在vector上运行一个循环,并对每个元素调用delete。

vector复制对象并存储该副本。现在在您的示例中,向量的类型是foo*。因此,当向vector传递指向foo的指针时,vector会复制该指针,而不是复制foo本身。现在当你重新赋值或者做其他事情的时候,指针的拷贝会被vector释放,而不是指针所指向的内存。假设您有一个键的向量,因此该向量复制传递给它的键,并释放键的副本。但它从来没有碰过钥匙所在的锁。你需要自己处理。您可以获取该值并在重新分配之前自己释放该元素。

如果foo是QObjects,那么分配给每个对象一个父对象(父对象将负责删除它们-尽管它们也可以手动删除)。在这种情况下,不要使用智能指针,因为这会产生所有权冲突。

最新更新