gpt4 book ai didi

c++ - 为什么在循环中调用 ReadConsole 会破坏堆栈?

转载 作者:可可西里 更新时间:2023-11-01 13:29:50 33 4
gpt4 key购买 nike

我已经使用以下代码禁用了行输入:

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 下运行它。

最佳答案

据我所知,这是 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);
}
}

sleep 使触发问题变得更容易一些,只要在您调用 ReadConsoleW 时有多个角色在等待,就会发生这种情况。 .

查看相关断言失败时 cBuf[1] 的内容,似乎 ReadConsoleW 在缓冲区末尾写入了一个额外的字节。

解决方法很简单:确保您的缓冲区至少有一个额外的字节。在您的情况下,使用双字符数组的第一个字符。

关于c++ - 为什么在循环中调用 ReadConsole 会破坏堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11875619/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com