在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?
Posted
技术标签:
【中文标题】在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?【英文标题】:What do I need to do before deleting elements in a vector of pointers to dynamically allocated objects?在删除指向动态分配对象的指针向量中的元素之前,我需要做什么? 【发布时间】:2011-05-02 23:09:02 【问题描述】:我有一个向量,我用指向对象的指针填充。我正在努力学习良好的内存管理,并且有几个一般性问题:
-
当我处理完向量后,是否必须循环遍历它并在每个指针上调用 delete?
为什么我不必在没有 new 语句的情况下对向量或我声明的任何其他变量调用 delete,但必须对指针调用 delete?
如果向量在返回的函数中声明(导致向量超出范围),C++ 是否会为我释放指针的内存?
【问题讨论】:
【参考方案1】:作为 David Titarenco 提到的 boost::ptr_vector
的替代方案,您可以轻松修改 std::vector 以自动释放内存以包含删除指针:
template<class T>
class Group : public std::vector<T>
public:
virtual ~Group() ;
;
template<class T>
class Group<T *> : public std::vector<T *>
public:
virtual ~Group()
std::vector<T *>::reverse_iterator it;
for (it = this->rbegin(); it != this->rend(); ++it)
delete *it;
;
std::vector 提供的所有功能都是继承的,因此您可以以相同的方式添加项目:
Group<Foo *> *bar = new Group<Foo *>();
bar->push_back(new Foo());
bar->push_back(new DerivedFoo());
// Deleting the Group will free all memory allocated by contained pointers
delete bar;
【讨论】:
【参考方案2】:当我完成向量后,我是否必须循环遍历它并在每个指针上调用 delete 是真的吗?
好吧,你不必手动循环,你也可以使用算法:
#include <vector>
#include <algorithm>
#include <memory>
int main()
std::vector<Base*> vec;
vec.push_back(new Derived());
vec.push_back(new Derived());
vec.push_back(new Derived());
// ...
std::for_each(vec.begin(), vec.end(), std::default_delete<Base>());
如果你没有 C++0x 编译器,你可以使用 boost:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>
std::for_each(vec.begin(), vec.end(), boost::lambda::delete_ptr());
或者您可以编写自己的函子:
struct delete_ptr
template <class T>
void operator()(T* p)
delete p;
;
std::for_each(vec.begin(), vec.end(), delete_ptr());
【讨论】:
【参考方案3】:您使用new
分配的所有内容稍后都必须分配给delete
。您未使用 new
显式分配的对象不应该是 delete
。
如果您不想手动管理对象但希望向量“拥有”它们,那么按值存储对象而不是存储指向它们的指针可能会更好。所以你可以用std::vector<SomeClass>
代替std::vector<SomeClass*>
。
【讨论】:
【参考方案4】:如果您可以访问 C++0x,也可以使用 std::unique_ptr。它取代了不能在容器中使用的已弃用的 std::auto_ptr。
【讨论】:
【参考方案5】:-
是的
向量是使用模板内存分配器实现的,它为您处理内存管理,因此它们有些特殊。但作为一般经验法则,由于堆栈和堆分配之间的差异,您不必对未使用
new
关键字声明的变量调用 delete
。如果在堆上分配了东西,则必须将其删除(释放)以防止内存泄漏。
没有。在遍历所有元素时,您必须明确调用 delete myVec[index]
。
例如:
for(int i = 0; i < myVec.size(); ++i)
delete myVec[i];
话虽如此,如果您打算将指针存储在向量中,我强烈建议您使用boost::ptr_vector
,它会自动处理删除。
【讨论】:
3:C++ 当然会释放指针使用的内存,因为它们是在堆栈上分配的。但是这些指针指向的对象很可能是在堆上分配的,因此需要被删除。当然,向量中的指针可以指向堆栈分配的对象,这些对象可能不会被删除。通常,您永远不应该将非常量指针存储到向量中,以堆栈分配的对象。以上是关于在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?的主要内容,如果未能解决你的问题,请参考以下文章