1

私には2つのクラスがあります。たとえばAとBです。クラスBには独自のデストラクタがあります。クラスA内に、クラスBのオブジェクトへのポインターのベクトルがあります。ベクトルは次のとおりです。

vector<B*> vect;

クラスAのデストラクタで、メモリを取得するにはどうすればよいですか?ベクトルを循環する場合、各オブジェクトを取得し、取得したすべてのオブジェクトに対して削除を使用しますか?デストラクタで試してみましたが、セグフォールトです。

この問題を解決するための助けは大歓迎です。申し訳ありませんが、コードを投稿できません。

4

6 に答える 6

3

Aがが指すものを所有している場合、Aは。内の各アイテムを所有vectできる必要があります。その間にsegfaultが発生した場合は、コードのどこかにバグがあります。deletevect

ただし、一般的には、スマートポインターを使用することをお勧めします。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();

編集: デストラクタでプログラムの segfault が発生した場合、コードは間違っています。ベクター内のアドレスごとにスタック要素を配置するかもしれませんが、オブジェクトを削除するには、ヒープ上にある必要があります。

#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 またはブースト)。

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

あなたの説明から、クラスAのvectメンバーは、B*が指すデータの生涯所有権を持っている必要があるように思われます。

その宣言を次のように変更することをお勧めします

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

編集:auto_ptrをstd :: tr1::shared_ptrに置き換えました

于 2010-06-24T20:41:51.273 に答える