0

作成したものの複数のオブジェクトを含めたいクラスがあります。現在機能するコードは次のとおりです。

process.h:

private:
  myObj *data;

process.cc:

data = new myObj[10];

ただし、コンストラクターに値を渡したいので、それをstd :: vectorに変換しようとしました(コンストラクターを変更して値を取得した後)。

process.h:

private:
  std::vector<myObj> data;

process.cc:

for (int m=0; m<10; m++) data.push_back( myObj(1.2) );

実行時にクラッシュするようにしようとすると

*** glibc detected *** ... corrupted double-linked list: ... ***

また、gdbのバックトレースは、割り当てた他の配列用にメモリを解放しようとしたときに、デストラクタでエラーが発生したことを示しています。検索では、明らかなものは何も表示されませんでした。でいくつかの静的メンバー変数を使用していますがmyObj、それが問題になる可能性がありますか?

4

2 に答える 2

3

二重削除バグが発生しています。次の簡単な例を考えてみましょう。

struct Other {};

struct MyObj {
    Other *p;

    MyObj () : p(new Other) {}
    ~MyObj () { delete p; }
};

std::vector<MyObj> data;

data.push_back(MyObj());

プッシュされる一時オブジェクトはdata適切に保存されます。ただし、一時的なものなので、プッシュするとすぐに破棄されます。つまり、p一時が破棄されるとメンバーが削除されるため、ベクトルのバージョンのコピーにはダングリング ポインターがあります。ベクター オブジェクトが破棄されると、ポインターが再び削除され、ヒープが破損します。あなたが受け取ったエラー メッセージはglibc、結果として悪い状態になったことを訴えるコードからのものでした。

この問題を解決するには、適切なコピー コンストラクターを定義して、オブジェクトの所有権を一時オブジェクトからコピー先に渡す必要があります。3 のルールでは、代入演算子も定義する必要があります。

struct MyObj {
    mutable Other *p;

    MyObj () : p(new Other) {}
    MyObj (const MyObj &o) : p(o.p) { o.p = 0; }
    ~MyObj () { delete p; }
    const MyObj & operator = (MyObj o) {
        using namespace std;
        swap(*this, o);
        return *this;
    }
};

pインスタンスが のときにメンバーを変更できるようにするには、ミュータブルを使用する必要がありconstconst一時変数がコピー コンストラクターに渡されるために必要でした。この変更により、アイテムをベクターにプッシュしても問題なく動作するようになりました。

より良い解決策は、代わりにpa を使用するように定義することです。unique_ptr

struct MyObj {
    std::unique_ptr<Other> p;

    MyObj () : p(new Other) {}
};

この例ではデストラクタは必要ありません。これは、デフォルトのデストラクタが p を破壊し、Otherインスタンスが によって削除されるためunique_ptrです。

于 2012-06-16T06:51:52.850 に答える
-1

ベクトルを使用してクラス内に複数のオブジェクトを格納しようとしていますか? 私もこの問題に遭遇しましたが、これを修正できる唯一の方法は、ベクターを使用している関数をヘッダーに配置することでした。私が信じているのは、ベクターに型 (この場合は myObj) を指定しているということですが、.cpp はベクターを定義した型を認識できません。そのため、ヘッダー内に関数を貼り付けると修正されるようです。これには他の方法があると思いますが、私は問題をあまり調べていません。

コード例:

class A
{
 private:
 vector<myObj> data;
 public:
 A();
 ~A();

 printData()
 {
     for(int i = 0; i < data.size(); i++)
     {
         printf("X position: %.2f Y position: %.2f Z position: %.2f \n", data.at(i).x, data.at(i).y, data.at(i).z);
     }
 };
}

これが問題である可能性があります。または、命名規則です。あなたが何をしているのかわかりませんが、data *myObj; はどのように機能しますか? およびデータ = 新しい myObj[10]; 実際に働く?myObj = new data[10] ではないでしょうか? もしそうなら、あなたのベクトルは次のようになります:

vector<data> myObj;
于 2012-06-16T01:30:33.270 に答える