0

演算子のオーバーロードの感触をつかもうとしていますが、問題が発生しました。このプログラムは、2 つの文字列をコンスすることだけを目的としています。これを行う他の方法が既にあることは知っていますが、私はプレイしたかったのです。次のエラーが表示されます。

ファイル: dbgdek.cpp 行: 52 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

これは私の delete [] の使用と関係があると思います。助けてください私は本当に立ち往生しています。

#include <iostream>
using namespace std;

class list{
public:
 char *value;
 int size;
 list(int s){size=s; allocmem();};
 ~list(){delete [] value;};
 list operator+(list);
private:
 void allocmem(void);
};

void list::allocmem(void){
 value=new char[size];
}

list list::operator+(list a)
{
 list t(a.size+size);
 for (int i=0; i<a.size; i++){
      t.value[i]=a.value[i];
 }
 for (int i=a.size; i<t.size; i++){
      t.value[i]=a.value[i-a.size];
 }
 return t;
}

int main ()
{
     list a(2),b(2),c(4);
     a.value[0]='a';
     b.value[0]='b';
     a.value[1]='c';
     b.value[1]='d';
     c=a+ b;
     for (int i=0; i<c.size; i++){
          cout<<c.value[i];
     }
     system("pause");
     return 0;
}

助けてください!

4

4 に答える 4

1

最初の警告サイン: あなたのクラスのデストラクタはいくつかのdeleteing を行いますが、クラスはコピー コンストラクタまたはコピー代入演算子を定義していません。

3 つのルールを参照してください。

オブジェクトの一時的なコピーを誤って作成し、一時的なデストラクタが呼び出されたときにそれらを台無しにしている可能性があります。

于 2010-12-03T16:06:23.447 に答える
1

デストラクタでメモリが重複して削除されないように、クラスに代入演算子 ( list::operator=(list const&)) とコピー コンストラクタ ( )を定義する必要があります。list::list(list const&)これらの関数を定義しない場合、コンパイラはそれらのデフォルトで生成されたバージョンを使用し、基本的にリスト オブジェクトのビットごとのコピーを作成します。リストのインスタンスをコピーした後、両方のインスタンスが同じポインター値を持ち、重複した削除が発生するため、これは悲惨です。

于 2010-12-03T16:06:26.487 に答える
0

次の 2 つのことを行う必要があります。

  1. データの独自のコピーを作成するコピー コンストラクターを作成する
  2. 値ではなく参照渡し。

で値渡しをしていますoperator +()。これにより、オブジェクトのコピーが渡されます(必要なものではなく、参照を渡したい)。しかし、コピー コンストラクターを作成しなかったため、コピーされたオブジェクトは既定のメンバーごとのコピーを取得します。現在、2 つのオブジェクトが同じポインターを持っています。最初のオブジェクトは問題なく削除され、2 番目のオブジェクトには無効なポインタが含まれています。

于 2010-12-03T16:05:16.270 に答える
0

char*文字列を直接操作する代わりに、std::string? 次に、メモリ管理の問題について心配する必要はありません (この場合、他の人が指摘したようにコピー コンストラクターを実装していないため、二重削除が発生します)。最も文字通りの翻訳では、次のようになります。

class list
{
public:
 std::string value;
 int size;
 list(int s){size=s; allocmem();}
 ~list(){}
 list operator+(list);
private:
 void allocmem(void);
};


void list::allocmem(void){
 value.resize(size);
}

より通常に使用するより良い実装がほぼ確実に存在することに注意してくださいstring(たとえば、なくなるsize可能性があります)。さらに、おそらくすべての属性を持つべきではありませんpublic

于 2010-12-03T16:54:38.043 に答える