我有一个像这样的指针向量:
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,那么分配给每个对象一个父对象(父对象将负责删除它们-尽管它们也可以手动删除)。在这种情况下,不要使用智能指针,因为这会产生所有权冲突。