0

これがプログラムです...

class CopyCon
{
public:
char *name;

CopyCon()
{ 
    name = new char; 
}

CopyCon(const CopyCon &objCopyCon)
{
    name = new char;
    _tcscpy(name,objCopyCon.name);
}

~CopyCon()
{
    if( name != NULL )
    {
        delete name;
        name = NULL;
    }
}
};

int main()
{
    CopyCon objCopyCon1;
    objCopyCon1.name = "Hai";
    CopyCon objCopyCon2(objCopyCon1);
    objCopyCon1.name = "Hello";
    cout<<objCopyCon2.name<<endl;
    return 0;
}

コードの実行が完了すると、デストラクタが呼び出されると、「delete」でクラッシュして...

デバッグエラー!

プログラム:..。

検出されたヒープ破損:0x00366990の通常ブロック(#124)の後。CRTは、ヒープバッファの終了後にアプリケーションがメモリに書き込んだことを検出しました。

(アプリケーションをデバッグするには、[再試行]を押します)

デストラクタのヒープメモリをクリアする必要はありません。このプログラムの何が問題になっていますか?誰か助けてください!コピーコンストラクターは、意図したとおりに完全に機能します。それでも... !?

4

7 に答える 7

5

char問題は、コピーコンストラクターに1つだけ割り当てていることです。

ここではmain、4バイトの文字列(nullを覚えておいてください)を割り当てていますが、オブジェクトをコピーするときは、1バイトに十分なスペースしか割り当てません。

あなたがおそらくやりたいのは変化です

name = new char;

name = new char[tcslen(objCopyCon.name) + 1];

そしてデストラクタでは:

delete name;

delete [] name;

また:

コンストラクターで割り当てられたメモリを割り当て、非表示"Hai"にします。このメモリは決して解放できません!"Hello"objCopyCon1.name

于 2010-04-22T06:45:23.367 に答える
4

割り当てられた変数を超えて書き込みますが、これは未定義の動作です。

次の行が実行されるとき

 CopyCon objCopyCon1;
 objCopyCon1.name = "Hai";
 CopyCon objCopyCon2(objCopyCon1);

_tcscpy()4文字(3文字とヌルターミネータ)を、合法的に1文字しか保持できないバッファにコピーします。したがって、バッファの終わりを超えて書き込むと、ヒープが破損します。

適切なサイズのバッファを割り当てる必要があります。

CopyCon(const CopyCon &objCopyCon)
{
    name = new char[_tcslen(objCopyCon.name) +1];
   _tcscpy(name,objCopyCon.name);
}

また、未定義の動作を回避するためdeleteに、デストラクタのをにdelete[]変更し、他のすべてのnew呼び出しをに変更する必要があります。new[]

于 2010-04-22T06:46:09.603 に答える
1

1つの文字を割り当て、そのメモリ位置に複数の文字をコピーしようとしています。最初に文字列の長さを調べてから、構文length + 1を使用して文字(NULL文字に対応するための余分な文字)を割り当てnew char[length+1]ます。それに応じて、デストラクタをに変更する必要がありますdelete[] name

于 2010-04-22T06:49:05.267 に答える
1

誰もが言及した問題に加えてnew char、文字列「Hai」と「Hello」は読み取り専用メモリに存在します。これは、それらを削除できないことを意味します(ただし、デストラクタで削除します)。これにより、クラッシュが発生します。コードをname直接割り当てるのではなく、次のような集合関数を使用する必要があります。

void set_name(const char *new_name)
{
    delete [] name; // delete is a no-op on a NULL pointer
    name = new char[tcslen(new_name) + 1];
    _tcscpy(name,new_name);
}

正直に言うと、割り当てによってコンパイラの警告が生成されないことに驚いています。あなたはにを割り当ててconst char *char *ます、それはあなたが見ているもののようなあらゆる種類の問題につながる可能性があります。

于 2010-04-22T07:03:09.117 に答える
0

保存しようとしている情報を保持するのに十分なメモリを割り当てる必要があります。「Hai」は4バイトまたは文字(ヌルターミネータを含む)であり、割り当てたのは1つだけです。また、「=」を使用して、あるメモリ位置から別のメモリ位置に文字列をコピーしないでください。文字列を横切ってstrncpyする必要があります。

std :: stringを使用すると、あなたの生活が100万倍楽になります:)

于 2010-04-22T06:48:15.783 に答える
0

ここに完璧に機能するコードがあります!

class CopyCon
{
public:
char *name;

CopyCon()
{ 
    name = NULL;        
}

CopyCon(const CopyCon &objCopyCon)
{
    name = new char[_tcslen(objCopyCon.name)+1];
    _tcscpy(name,objCopyCon.name);
}

~CopyCon()
{
    if( name != NULL )
    {
        delete[] name;
        name = NULL;
    }
}

void set_name(const char *new_name) 
{ 
    //delete [] name; // delete is a no-op on a NULL pointer 
    if( NULL != name)
    {
        delete[] name; name = NULL;
    }
    name = new char[_tcslen(new_name) + 1]; 
    _tcscpy(name,new_name); 
} 
};

int main()
{
     CopyCon objCopyCon1;
objCopyCon1.set_name("Hai");
CopyCon objCopyCon2(objCopyCon1);
objCopyCon1.set_name("Hello");
cout<<objCopyCon1.name<<endl;
cout<<objCopyCon2.name<<endl;
return 0;
}

彼らの視点をありがとう。本当に助かりました!

于 2010-04-22T07:52:47.833 に答える
0

の仕事はcopy ctor、オブジェクトのコピーを作成することです。したがって、両方のオブジェクトでがchar指す配列は、とである必要がありますが、これはあなたの場合には発生しません。だから変更namesame sizesame content

name = new char; // allocates only one char

name = new char[strlen(objCopyCon.name) + 1]; // allocate array of char
于 2010-04-22T06:47:30.200 に答える