1

このオペレーターオーバーローダーがあります。新しいwchar_t配列の作成時にプログラムがクラッシュします。

myObject &operator += (const myObject &s) {
    wchar_t *cat = wcscat(data, s.data);
    int len = wcslen(cat);
    wchar_t *test = new wchar_t[len + 1]; //this is killing!
    wcscpy(test, cat);

    delete data;
    data = test;

    return *this;
}

何が起こっているか知っている人はいますか?

完全なクラス定義を編集

class myObject
{
    private:
        wchar_t *data;
    public:
        myObject() { data = 0; }
        ~myObject() { delete data; }

        myObject &operator += (const myObject &s) {
            wchar_t *cat = wcscat(data, s.data);
            int len = wcslen(cat);
            wchar_t *test = new wchar_t[len + 1];
            wcscpy(test, cat);

            delete data;
            data = test;

            return *this;
        }
};
4

2 に答える 2

3

このコードには、少なくとも 2 つの明らかな問題が含まれています。

  1. 明らかに を使用してデータを割り当てますが、 を使用するのではなく を使用new wchar_t[n]して解放します。delete pdelete[] p
  2. 問題の原因として考えられるのは、2 つの文字列を 1 つの文字列のメモリに連結し、データをコピーするのに十分なメモリ割り当てたことです。

おそらく、これに沿ってもっと何かが必要です:

myObject &operator += (const myObject &s) {
    size_t len = wcslen(this->data) + wcslen(s.data);
    std::unique_ptr<wchar_t[]> tmp(new wchar_t[len + 1]);
    wcscpy(tmp.get(), this->data);
    wcscat(tmp.get(), s.data);
    delete[] this->data;
    this->data = tmp.release();
    return *this;
}

実際、あなたは を使いたいと思いますstd::wstring: このクラスはすでにロジックを提供しています。

于 2012-11-10T14:56:16.793 に答える
2

Dietmar が言うように (ただし、舞台裏でおそらく何が起こったのかもう少し詳しく説明します):

1) 呼び出しwcscat(data, s.data)が、 が指すバッファの終わりをオーバーランしましたdata。オーバーランしない場合は、既存のバッファーで十分な大きさになるため、新しいバッファーを割り当てる必要はありません。十分な大きさではないと思います。

2) バッファのオーバーランの結果として、メモリ アロケータによって使用されるデータ構造が破棄されます。これにより、メモリを割り当てようとするとクラッシュが発生します。メモリを解放するときに簡単にクラッシュするか、まったくクラッシュしない可能性があります。

于 2012-11-10T15:02:50.570 に答える