Почему вызов ReadConsole в цикле повреждает стек?

Я отключил линейный ввод с помощью следующего кода:

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, когда программа существует, она вылетает с:

Run-Time Check Failure #2 - Stack around the variable 'cBuf' was corrupted.

Почему это приводит к повреждению стека? Код простой, поэтому я не могу понять, что не так.

Небольшая программа, с помощью которой я могу воспроизвести проблему:

#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, и она вылетает с повреждением стека.

Я также не могу воспроизводить проблему каждый раз, требуется несколько попыток.
Я запускал его в Visual Studio 2010 после создания нового пустого консольного проекта и добавления файла с этим кодом.

5
задан Josh 9 August 2012 в 03:27
поделиться