0

「*** glibc が検出されました *** /home/ubuntu[....] : 二重解放または破損 (fasttop) : 0x09851168 ***」という問題があります。

問題の原因と思われる行を見つけました。

data[i]->~Class();

これは

 class Class {
public:
    Class();
    Class(char *name, double value);
    virtual ~Class();
    char *name;
    double value;
private:

};

それから

    Class::Class() {
}

Class::Class(char* name, double value){
    this->name = new char[std::strlen(name)];
    std::strcpy(this->name, name);
    this->value = value;
}

Class::~Class() {
    delete name;
}

今、明らかに私はそこで何か間違ったことをしています。誰でも私に何を教えてもらえますか?

4

3 に答える 3

7

あなたが間違っているのは、明示的にデストラクタを呼び出すことです:

data[i]->~Class();

明示的に呼び出す必要があることを完全に知っている場合を除き (これは珍しいことであり、多くの巨大なプログラムではそれを行う必要はありません)、おそらく代わりに次を使用する必要がありますdelete

delete data[i];
于 2012-04-11T02:25:20.653 に答える
1

私はあなたが使用するいくつかの状況を知っています:data[i]->~Class();。1つは、新しい配置を使用して、その場所にオブジェクトを作成していることです。もう1つは、オブジェクトを破棄して再初期化し、すぐに配置newを使用してそこに新しいオブジェクトを作成することです。これらはどちらもかなり高度な手法であり、率直に言って、独自のコレクションクラスを作成している場合を除いて、かなり珍しいものです。

私の推測では、1)それは必要ない、2)重要なコード(ほとんどの場合、明示的なdtor呼び出しを取り巻くもの)を実際に示していないということです。

で割り当てnamenew[]削除することで、もう1つ小さな問題が発生しdelete name;ます。2つは一致するはずなので、を使用する必要がありますdelete [] name;。ただし、これが一連の技術であることを考えると、これはcharほとんど技術的なことです。この場合、問題が発生することはほぼ間違いありません。それが重要なデストラクタを持つオブジェクトの配列である場合、典型的な症状は、オブジェクトの一部(ほとんど)が適切に破壊されなかった(つまり、デストラクタが呼び出されなかった)ことです。理論的には、これは未定義の動作であるため、何か発生する可能性がありますが、問題の原因となる可能性は非常に低くなります(特に、の配列の場合char)。

もちろん、あなたが本当にすべきことはnamestd::stringとにかくすべてのナンセンスを完全にスキップすることです。

于 2012-04-11T02:29:33.740 に答える
1
data[i]->~Class();

そのようなデストラクタを呼び出すべきではありません。で割り当てdeleteられた場合new、または何もせず、オブジェクトがスコープ外になったときにデストラクタが呼び出されます。

于 2012-04-11T02:25:51.280 に答える