仅当我使用“免费”(发布版)中的 WinDDK nmake 编译器进行构建(执行优化)时,才会出现此错误。我无法在“已检查”构建或使用 VS 编译中重现此问题。
这是我的代码中发生的伪代码:
main()
{
//variable init and other code
fprintf(log, "pre nullValue: %lu\n", NULL); //printf added for debugging
otherFunc();
funcWithError(str1, str2, NULL);
fprintf(log, "post nullValue: %lu\n", NULL);
fprintf(log, "post2 nullValue: %lu, %lu, %lu\n", NULL, 0, NULL);
}
BOOL otherFunc()
{
//variable init and other code
callToDll();
//...doing stuff
libusb_usb_open(var1); //If I remove this line there is no problem!!
//...doing more stuff
}
BOOL funcWithError(char* s1, char* s2, FUNC_PTR fp)
{
fprintf(log, "inFunc nullValue: %lu, %lu\n", NULL, fp);
if(fp != NULL)
return FALSE; //This line is being executed erroneously!!
}
Output in log:
pre nullValue: 0
inFunc nullValue: 0, 251208
post nullValue: 251208
post2 nullValue: 251208, 251208, 251208
Note: The re-occurring number (251208) is a different number each time the program is run
只需更改这一行即可修复/导致它。这是libusb usb_open称呼。
- 最终我的问题是找出如何解决问题(我无法避免这个电话)
- 但是在堆栈/内存管理级别上,如何可能让 NULL 不为零并且将文字值“0”打印为非零?
让我知道哪些其他信息可能有帮助......
最佳答案
并非完全灌篮。但堆栈很可能变得不平衡。在调试器中(是的,您可以调试发布版本),在调用之前和之后检查 ESP 寄存器的值。应该是一样的。如果函数的调用约定错误,则不会。就像 __stdcall 与 __cdecl 一样。
当您使用 nmake.exe 构建程序时,这可以很好地隐藏自己,很容易忘记在调试构建中打开/RTCs 选项,从而发出堆栈检查代码。 ESP 寄存器往往会在函数返回时自行恢复。直到您构建发布版本,其中函数被内联并且 EBP 的使用被优化,因此 ESP 不再自行恢复。
关于c++ - 奇怪的内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5917950/