Jos*_*osh 5 c++ windows winapi stack-corruption
我已使用以下代码禁用了行输入:
DWORD dwConsoleMode;
GetConsoleMode(hStdIn, &dwConsoleMode);
dwConsoleMode ^= ENABLE_LINE_INPUT;
SetConsoleMode(hStdIn, dwConsoleMode);
Run Code Online (Sandbox Code Playgroud)
然后我在循环中调用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;
}
Run Code Online (Sandbox Code Playgroud)
如果我运行程序并立即按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;
}
Run Code Online (Sandbox Code Playgroud)
你必须在运行它之后将键盘进行混搭,然后按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);
}
}
Run Code Online (Sandbox Code Playgroud)
睡眠使得触发问题变得容易一些,只要在您调用ReadConsoleW时多个字符正在等待就会发生这种情况.
查看cBuf[1]相关断言失败时的内容,看起来ReadConsoleW在缓冲区末尾写了一个额外的字节.
解决方法很简单:确保缓冲区至少有一个额外字节.在您的情况下,使用双字符数组的第一个字符.
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |