1

私はこの振る舞いを理解することができません。私はクラスAを持っています、

class A
{
public:
int ch;
char *s;
A()
{}
A(char *st):ch(0)
{
    s = new char[10];
    strcpy(s,st);

}
A(const A& rhs):ch(rhs.ch)
{
    s = new char[strlen(rhs.s)+1];
    strcpy(s,rhs.s);
}
const A& operator=(const A& rhs)
{
    char *temp = new char[strlen(rhs.s)+1];
    strcpy(temp,rhs.s);
    delete[] s;
    s=temp;
    ch = rhs.ch;
    return *this;
}
~A()
{
    delete []s;
}
};

この時点まで、すべてが期待どおりに進み、コピーコンストラクターと代入演算子をテストでき、それらは正しく機能しています。

子クラスBを作成しましたが、ヒープ破損エラーが発生します。理解できませんが、これはクラスAのデストラクタに関連する問題ですか。?以下は私のクラスBです。

class B:public A
{

public:
int a;
B():a(0){}
};
4

3 に答える 3

3

問題を解決するには、次のものを交換するだけです。

char *s;

std::string s;

を介して手動のメモリ管理を取り除くだけですchar *。これがまさにC++が提供する理由ですstd::string

何が問題なのでしょう?

引数をとらないデフォルトのコンストラクターは、動的な割り当てを行いません。
このコンストラクタを介してクラスオブジェクトを作成した場合、デストラクタはdelete、割り当てられていないポインタを取得することにnewなり、その結果、未定義動作が発生します。

于 2013-01-04T08:05:40.507 に答える
3

デストラクタでは、あなたdelete[] s;はですが、デフォルトのコンストラクタでは、new[]sを編集していません。実際、あなたはまだ初期化していないs

基本クラスのデフォルトコンストラクタは、派生クラスをインスタンス化するときに呼び出されます。これは、他の方法で基本を初期化していないためです(: A(...))。したがって、何を削除するのか、明日の朝食に何を用意するのかさえ、未定義の動作であるため、わかりません。

一貫性を保つためnew[]に、デフォルトのコンストラクターでsを使用します。std::string頭痛の種を減らすために、文字ポインタの代わりに次のようなものを提案します。

于 2013-01-04T08:06:28.577 に答える
3

のデフォルトのコンストラクターは、メンバー(ポインター)Aを初期化しません。s

A()
{}

したがって、このコンストラクタを使用して要素を構築すると、デストラクタが初期化されていない要素を削除するとクラッシュします。

~A()
{
  delete []s;
}

クラスBはのデフォルトコンストラクタを使用するためA、この問題が発生します。デフォルトのコンストラクターですべてのメンバーを適切に初期化することにより、これを回避します。

A() : ch(), s(0)
{ }
于 2013-01-04T08:08:03.970 に答える