6

次のコードで行入力を無効にしました:

DWORD dwConsoleMode;
GetConsoleMode(hStdIn, &dwConsoleMode);
dwConsoleMode ^= ENABLE_LINE_INPUT;
SetConsoleMode(hStdIn, dwConsoleMode);

次に、ループ内でReadConsoleを呼び出しています...ループ内:

wchar_t cBuf;

while (1) {
    /* Display Options */

    do {
        ReadConsole(hStdIn, &cBuf, 1, &dwNumRead, NULL);
    } while (!iswdigit(cBuf));

    putwchar(cBuf);

    if (cBuf == L'0') break;
}

プログラムを実行してすぐに0を押すと、きれいに存在します。
しかし、私がたくさんのキーを押してから0を押すと、プログラムが存在するときに次のようにクラッシュします。

実行時チェックの失敗#2-変数'cBuf'の周りのスタックが破損しました。

これによりスタックが破損するのはなぜですか?コードは単純なので、何が悪いのかわかりません。

問題を再現できる小さなプログラム:

#include <windows.h>
#include <stdio.h>

int wmain(int argc, wchar_t *argv[])
{
    DWORD dwNumRead;
    wchar_t cBuf;

    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);

    DWORD dwConsoleMode;
    GetConsoleMode(hStdIn, &dwConsoleMode);
    dwConsoleMode ^= ENABLE_LINE_INPUT;
    SetConsoleMode(hStdIn, dwConsoleMode);

    while (true)
    {
        wprintf(L"\nEnter option: ");

        do {
            ReadConsoleW(hStdIn, &cBuf, 1, &dwNumRead, NULL);
        } while (!iswdigit(cBuf));

        putwchar(cBuf);

        if (cBuf == L'0') break;
    }

    return 0;
}

キーボードを実行した後、キーボードをマッシュする必要があります。次に0を押すと、スタックが破損してクラッシュします。

また、毎回問題を再現することはできません。数回の試行が必要です。
新しい空のコンソールプロジェクトを作成し、そのコードを含むファイルを追加した後、VisualStudio2010で実行していました。

4

1 に答える 1

8

私の知る限り、これはWindowsのバグです。これは、問題を示す少し単純なプログラムです。

#include <windows.h>
#include <crtdbg.h>

int wmain(int argc, wchar_t *argv[])
{
    DWORD dwNumRead;
    wchar_t cBuf[2];

    cBuf[0] = cBuf[1] = 65535;

    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    SetConsoleMode(hStdIn, 0);

    while (true)
    {
        _ASSERT(ReadConsoleW(hStdIn, &cBuf[0], 1, &dwNumRead, NULL));
        _ASSERT(dwNumRead == 1);
        _ASSERT(cBuf[1] == 65535);
        Sleep(5000);
    }
}

スリープにより、問題のトリガーが少し簡単になります。この問題は、 ReadConsoleWを呼び出すときに複数の文字が待機しているときに発生します。

関連するアサーションが失敗したときの内容を見ると、cBuf[1]ReadConsoleWがバッファの最後に1バイト余分に書き込んでいるように見えます。

回避策は簡単です。バッファに少なくとも1バイト余分にあることを確認してください。あなたの場合、2文字の配列の最初の文字を使用してください。

于 2012-08-09T04:46:37.003 に答える