我将某些来源从VC6转换为VS2010。代码是用C ++ / CLI编写的,它是一个MFC应用程序。它包括一行:
BYTE mybyte;
sscanf(source, "%x", &mybyte);
VC6(15年以上)没问题,但在VS2010中造成问题,所以我创建了一些测试代码。
void test_WORD_scanf()
{
char *source = "0xaa";
char *format = "%x";
int result = 0;
try
{
WORD pre = -1;
WORD target = -1;
WORD post = -1;
printf("Test (pre scan): stack: pre=%04x, target=%04x, post=%04x, sourse='%s', format='%s'\n", pre, target, post, source, format);
result = sscanf(source, format, &target);
printf("Test (post scan): stack: pre=%04x, target=%04x, post=%04x, sourse='%s', format='%s'\n", pre, target, post, source, format);
printf("result=%x", result);
// modification suggested by Werner Henze.
printf("&pre=%x sizeof(pre)=%x, &target=%x, sizeof(target)=%x, &post=%x, sizeof(post)=%d\n", &pre, sizeof(pre), &target, sizeof(target), &post, sizeof(post));
}
catch (...)
{
printf("Exception: Bad luck!\n");
}
}
构建它(在DEBUG模式下)没问题。运行它会产生奇怪的结果,我无法解释。首先,我按预期得到两个printf statemens的输出。然后得到一个运行时间,这对我来说是意想不到的。
Test (pre scan): stack: pre=ffff, target=ffff, post=ffff, source='0xaa', format='%x'
Test (post scan): stack: pre=ffff, target=00aa, post=ffff, source='0xaa', format='%x'
result=1
Run-Time Check Failure #2 - Stack around the variable 'target' was corrupted.
使用调试器我发现从函数返回时会触发运行时检查失败。有人知道运行时检查失败的来源吗?我使用谷歌但无法找到任何建议。
在实际代码中,它不是在sscanf中使用的WORD而是BYTE(我有测试函数的BYTE版本)。这导致实际的堆栈损坏与"%x"使用"%hx"格式(用0覆盖变量pre) (我希望是正确的格式)仍然会在覆盖变量prev的低字节时引起一些问题。
欢迎提出任何建议。
注意:我编辑了示例代码以包含sscanf()
的返回结果亲切的问候,
Andre Steenveld。
答案 0 :(得分:0)
sscanf
与%x
writes an int
。如果提供BYTE
或WORD
的地址,则会出现缓冲区溢出/堆栈覆盖。 %hx
将write a short int
。
解决方案是使用int变量,让sscanf
写入该变量,然后将WORD
或BYTE
变量设置为读取值。
int x;
sscanf("%x", "0xaa", x);
BYTE b = (BYTE)x;
BTW,您的测试和消息
运行时检查失败#2 - 变量'target'周围的堆栈已损坏。
你还应该打印出变量的地址,你可能会看到编译器在pre / target / post变量之间添加了一些填充/安全检查空间。