我有2个班,比如A& B. B类有自己的析构函数。在A类中,我有一个指向B类对象的指针向量。向量如下:
vector<B*> vect;
在A类的析构函数中,如何检索内存?如果我循环遍历向量,我是否检索每个对象并对每个检索到的对象使用删除?我在析构函数中尝试了这一点,但它是段错误的。
欢迎任何解决此问题的帮助。对不起,我不能发布代码。
答案 0 :(得分:4)
如果A拥有vect
指向的内容,那么它应该delete
vect
内的每个项目。如果它在执行此操作时出现段错误,那么您的代码中就会出现错误。
但总的来说,你最好使用智能指针。 Boost的ptr_vector(Boost.Pointer Container的一部分是为您的特定示例而设计的,但简单的std::vector<std::tr1::shared_ptr<B> >
也可以使用(虽然有更多的开销和更笨拙的语法)。
答案 1 :(得分:1)
如果类型B*
的项指向堆上分配的对象,则为是,然后对于每个项应调用delete。
答案 2 :(得分:1)
其他一些帖子指出你最好使用智能指针而不是指针。如果由于任何原因必须使用指针,则应首先在循环中删除它们。
for ( std::vector<B*>::iterator it = vect.begin(); it != vect.end(); ++it)
delete (*it);
vect.clear();
编辑: 如果您的程序在析构函数中出现段错误,那么您的代码是错误的。也许你通过地址将堆栈元素放在向量中,但要删除一个对象,它必须在堆上。
#include <iostream>
#include <vector>
#include <string>
class data {
public:
std::string d;
data(std::string _d) : d(_d) { }
};
class container {
public:
std::vector<data*> c;
container() { c.clear(); }
void add (data *d) { c.push_back(d); }
~container() {
for (std::vector<data*>::iterator it = c.begin(); it != c.end(); ++it)
delete (*it);
c.clear();
}
};
int main (int argc, char* argv[]) {
typedef std::vector<std::string> sVec;
typedef sVec::iterator sVecIter;
std::vector<std::string> cmd (argv+1, argv+argc);
{
container k;
for (sVecIter it = cmd.begin(); it != cmd.end(); ++it)
k.add(new data((*it)));
}
return 0;
}
这没有问题。
答案 3 :(得分:0)
是的,你会循环向量并删除每个项目。问题是你忘记了第42行的毛巾操作员。
答案 4 :(得分:0)
当您需要管理其生命周期时,您希望避免将指针存储在容器中。
如果这是一个真正的所有者,并保证最后清理,那么我会选择
std::vector<B> vect;
如果您有不同的引用和生命周期可能重叠,那么shared_ptr会更好(std :: tr1或boost取决于编译器)
std::vector< boost::shared_ptr<B> > vect;
答案 5 :(得分:-1)
根据您的描述,听起来您的A类vect成员应该拥有B *指向的数据的终身所有权。
我建议只将该声明更改为
vector< std::tr1::shared_ptr<B> > vect;
编辑:用std :: tr1 :: shared_ptr
替换auto_ptr