3

Visual C++ ランタイムによると、デストラクタで free を呼び出すとヒープが破損します。しかし、ヒープが破損する理由がわかりません。誰か説明できますか? 正確なエラーは次のとおりです。

CRT detected that the application wrote to memory after end of heap buffer.

また、プログラムがクラッシュしないというエラーを無視すると、プログラムは実行され続け、キーを押すと 0 が返されます。

このクラスには、コンストラクタとデストラクタ、およびプライベート変数FILE* targetchar* raw_data.

foo::foo (wchar_t* path)
{
    size_t size;

    target = _wfopen (path, L"rb+");
    if (!target) {
        char* error = strerror (errno);
        printf ("The file could not be opened: %s\n", error);
        _exit (1);
    }

    fseek (target, 0L, SEEK_END);
    size = ftell (target);
    fseek (target, 0, SEEK_SET);
    raw_data = (char*) malloc (size);
    size = fread (raw_data, 1, size, target);
    raw_data[size] = '\0';
}

foo::~foo ()
{
    fclose (target);
    free (raw_data);
}

int main ()
{
    nbt* klas = new nbt (L"C:\\Users\\Ruben\\level");
    puts ("Success?!");
    delete klas;
    getchar ();
    return 0;
}
4

2 に答える 2

4

NULあなたがするようにターミネータを書くとき:

raw_data[size] = '\0';

...割り当てたバイトよりも1バイト多く使用しています。他のエラーがあるかもしれませんが、この行には間違いなくエラーがあります。割り当てていないメモリへの書き込みは「未定義の動作」であり、観察しているクラッシュを説明できます。

于 2013-08-14T16:54:28.510 に答える
3

1 つの確かな問題は、次のコードです。

raw_data = (char*) malloc (size);
size = fread (raw_data, 1, size, target);
raw_data[size] = '\0';

raw_data[size]割り当てられたサイズを超えているため、 にアクセスできません。C/C++ のインデックス アクセスはゼロベースです。その結果、raw_data既存のコードでアクセスできる の最後の要素は ですraw_data[size-1]。オフセットにあるバイトをゼロに設定できるようにするには、次のsizeように変更する必要がありますmalloc

raw_data = (char*) malloc (size+1);

これは C++ アプリケーションであるため、FILE ポインタと malloc/free の代わりにストリームと new/delete を使用することをお勧めします。

于 2013-08-14T16:55:14.283 に答える