0

ビジュアル スタジオ 2010

char 文字列にメモリを割り当て、その文字列 (ポインタ) を関数に渡し、メモリを解放しようとすると、「ヒープ破損が検出されました」という実行時エラーが発生します。

これは、メモリが返されたときにメモリを「解放済み」としてマークする関数の結果であると思われますが、これを回避する方法についてはまだ困惑しています。free() の呼び出しを単純に削除するのは気が進まない。

// this function takes a char string, converts it to a wide char string, 
// then passes the converted string to another function.
void Class::WriteToLog(const char * msg)
{
    // allocate memory
    wchar_t * wMsg = (wchar_t*)malloc((strlen(msg) * sizeof(wchar_t)) + 1); // add one for null terminating char
    // convert to wide char. This works fine, and returns 4 when msg is 4 chars long.
    numChar = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, msg, strlen(msg), wMsg, strlen(msg));

    wMsg[numChar] = L'\0'; // terminate string
    // At this point wMsg contains the same thing msg contains. Works fine.
    WriteToLogW(wMsg); // Works fine. Writes the string to a text file.
    free(wMsg); // Heap Corruption Detected
}


void Class::WriteToLogW(const wchar_t * msg)
{
    ...
}
4

2 に答える 2

2

s は 1 バイトであるため (したがって、null ターミネータは 1 バイトを占有します)、sを操作するとき+1に、最後に追加したmallocは null ターミネータに十分なメモリのみを割り当てます。charchar

を使用しているためwchar_t、null ターミネータはsizeof(wchar_t)バイトを占有しますが、これは事実上常に 1 より大きくなります。したがって、このmalloc呼び出しでは不十分なメモリが割り当てられます。malloc呼び出しを次のように再構成します。

wchar_t * wMsg = (wchar_t*) malloc((strlen(msg) + 1) * (sizeof(wchar_t));

このようにして、割り当てられたバイトの合計数にヌル ターミネータの余地が残されます。

于 2014-01-30T22:24:59.853 に答える
2

ワイド文字列の終端の nul でさえ幅が広いため、1 バイトだけでは十分ではありません。変化する:

wchar_t * wMsg = (wchar_t*)malloc((strlen(msg) * sizeof(wchar_t)) + 1);

wchar_t * wMsg = (wchar_t*)malloc((strlen(msg) + 1) * sizeof(wchar_t));
于 2014-01-30T22:25:09.397 に答える