我有一个向量,我用指向对象的指针填充。我正在努力学习良好的记忆管理,并提出一些一般性问题:
答案 0 :(得分:23)
delete
关键字声明的变量调用new
,因为堆栈和堆分配之间存在差异。如果在堆上分配了东西,则必须删除它(释放)以防止内存泄漏。delete myVec[index]
。例如:
for(int i = 0; i < myVec.size(); ++i)
delete myVec[i];
话虽如此,如果您计划在向量中存储指针,我强烈建议使用boost::ptr_vector
自动处理删除。
答案 1 :(得分:11)
当我完成向量时,我必须遍历它并在每个指针上调用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());
答案 2 :(得分:3)
如果您有权访问C ++ 0x,也可以使用std :: unique_ptr。它取代了不能在容器中使用的已弃用的std :: auto_ptr。
答案 3 :(得分:3)
您使用new
分配的所有内容以后都必须delete
。您未使用new
明确分配的对象不应该delete
。
如果您不想手动管理对象但希望向量“拥有”它们,那么最好按值存储对象而不是存储指针。因此,您可以使用std::vector<SomeClass*>
代替std::vector<SomeClass>
。
答案 4 :(得分:2)
作为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;