1

我有 2 个类,比如 A 和 B。B 类有自己的析构函数。在 A 类中,我有一个指向 B 类对象的指针向量。该向量如下:

vector<B*> vect;

在 A 类的析构函数中,如何检索内存?如果我循环遍历向量,是否检索每个对象并在每个检索到的对象上使用 delete?我在析构函数中尝试过,但它出现了段错误。

非常欢迎解决此问题的任何帮助。很抱歉,我无法发布代码。

4

6 回答 6

3

如果 A 拥有 所指向的东西vect,那么它应该能够拥有delete内的每一项vect。如果这样做时出现段错误,那么您的代码中某处有错误。

不过,一般来说,您最好使用智能指针。Boost 的ptr_vectorBoost.Pointer Container的一部分是为您的特定示例而设计的,但一个简单的std::vector<std::tr1::shared_ptr<B> >也可以工作(尽管有更多的开销和更尴尬的语法)。

于 2010-06-24T20:42:07.107 回答
1

是的,如果类型的项目B*指向在堆上分配的对象,那么对于每个项目,您都应该在其上调用 delete。

于 2010-06-24T20:38:16.940 回答
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;

}

这没有问题。

于 2010-06-24T21:06:03.507 回答
0

是的,您将循环向量并删除每个项目。问题是您忘记了第 42 行的毛巾操作员。

于 2010-06-24T20:40:10.693 回答
0

当您需要管理指针的生命周期时,您希望避免将指针存储在容器中。

如果这是一个真正的所有者,并且保证是最后一次清理,那么我会选择

std::vector<B> vect;

如果您有可能重叠的不同引用和生命周期,那么 shared_ptr 会更好(std::tr1 或 boost 取决于编译器)

std::vector< boost::shared_ptr<B> > vect;
于 2010-06-24T20:49:32.980 回答
-1

根据您的描述,听起来您的 A 类 vect 成员应该拥有 B* 指向的数据的终身所有权。

我建议将该声明更改为

vector< std::tr1::shared_ptr<B> > vect;

编辑:用 std::tr1::shared_ptr 替换 auto_ptr

于 2010-06-24T20:41:51.273 回答