0

コードに問題があります。BLOCK_TYPE_IS_VALID のエラーが表示されます... new と delete に問題があることはわかっていますが、見つかりません。これらの関数を持つ myString クラスがあります。

    //constructors and destructors
myString::myString() {
    this->string_ = NULL;
    this->length = 0;

    cout << "created " << "NULL" << endl;
}

myString::myString(char a[]) {
    int i;
    for (i=0; a[i]!=NULL; i++);
    this->length = i;

    int j=0;
    while(pow(2,j)<i)
        j++;

    this->string_ = new char [(int)pow(2,j)];
    for (int i=0; i<this->length; i++)
        this->string_[i] = a[i];

    cout << "created " << this->string_ << endl;
}

myString::~myString() {
    cout << "deleteing " << this->string_ << endl;
    if (this->string_ != NULL)
        delete [] this->string_;
}

そして、これを実行すると

myString a("aaa");
myString b("bbbb");
myString c;
c = a + b;
cout << c.get_lenght() << endl;
cout << c.get_string() << endl;

「c = a+b」行でエラーが発生し、プログラムが停止します。

4

2 に答える 2

3

クラスのコピー コンストラクター代入演算子を定義する必要があります。

myString::myString( const myString& );
myString& operator=( const myString& );

そうしないと、3 つのルールに違反しています。

このコード...

c = a + b;

myString値を保持する一時的な を生成する場合がありますa + b

デフォルトで生成されたコピーと割り当ての実装は、一時的なものc と同じstring_ポインターを提供します。

そして、これらの文字列のいずれかのデストラクタが実行されると、もう一方の文字列にはダングリング ポインターが含まれます。

偶然にも、このコード:

if (this->string_ != NULL)
    delete [] this->string_;

単純に異なる動作をすることはありません:

delete [] this->string_;
于 2013-04-01T17:55:02.500 に答える
1

クラス定義を示していませんが、Rule of Three に従っていないと思います。

正しく実装されたコピー コンストラクターとコピー代入演算子がなければ、オブジェクトを安全にコピーすることはできません。デフォルトの実装では、ポインター (および他のメンバー変数) を単純にコピーし、両方のコピーを残して、デストラクタ内の同じメモリ ブロックを削除します。

最も簡単な解決策は、メモリを管理するように設計されたクラスを使用することです。std::stringまたはstd::vector<char>ここで理想的です。

自分でメモリを管理する正当な理由があると仮定すると、次のようなものが必要になります。

// Copy constructor
myString(myString const & other) :
    string_(new char[other.length]),
    length(other.length)
{
    std::copy(other.string_, other.string_+length, string_);
}

// Simple assignment operator
// For bonus points (and a strong exception guarantee), use the copy-and-swap idiom instead
myString & operator=(myString const & other) {
    if (this != &other) {
        delete [] string_; // No need to check for NULL (here or in the destructor)
        string_ = new char[other.length];
        length = other.length;
        std::copy(other.string_, other.string_+length, string_);
    }
    return *this;
}

C++11 では、さらにボーナス ポイントを得るために、move コンストラクターと代入演算子も提供することを検討してください。これらはポインターを変更するだけでよいため、コピーするよりもはるかに効率的です。

于 2013-04-01T17:57:00.463 に答える