2008-12-12 35 views
1

这使我疯狂。我使用在Windows的.lib,一些第三方的代码,在调试模式,是造成类似如下的错误:无法追踪潜在的内存覆盖。窗口奇怪

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

将引发错误或者当对象超出范围或被删除。简单地分配这些对象之一,然后删除它会抛出错误。因此,我认为问题出现在许多构造函数/析构函数之一中,但是尽管遍历了每行代码,但我无法找到问题所在。

但是,只有在静态库中创建这些对象时才会发生这种情况。如果我在我的EXE应用程序中创建一个,错误不会出现。第三方代码本身位于静态库中。例如,此操作失败:

**3RDPARTY.LIB** 

class Foo : public Base 
{ 
    ... 
}; 

**MY.LIB** 

void Test() 
{ 
    Foo* foo = new Foo; 
    delete foo; // CRASH! 
} 

**MY.EXE** 

void Func() 
{ 
    Test(); 
} 

但是这将工作:

**3RDPARTY.LIB** 

class Foo : public Base 
{ 
    ... 
}; 

**MY.EXE** 

void Func() 
{ 
    Foo* foo = new Foo; 
    delete foo; // NO ERROR 
} 

所以,切割出“中间”的.lib文件使问题消失,正是这种weridness是推动我狂。 EXE和2个库都使用相同的CRT库。没有错误链接。第三方代码使用继承,并且有5个基类。我尽可能多地评论了代码,同时仍然可以构建代码,而我只是看不到发生了什么。

因此,如果有人知道为什么.lib中的代码对.exe中的相同代码采取不同的行为,我很乐意听到它。同上任何提示追踪内存覆盖!我正在使用Visual Studio 2008.

回答

2

好的,我追踪了这个问题,如果有人感兴趣的话,它就是一个破解者。基本上,我的.LIB,展示了这个问题。已将_WIN32_WINNT定义为0x0501(Windows 2000及更高版本),但我的EXE和第三方LIB将其定义为0x0600(Vista)。现在,由第三方LIB包括在报头中的一个是sspi.h它定义了一个称为SecurityFunctionTable结构,其包括下面的代码片断:

#if OSVER(NTDDI_VERSION) > NTDDI_WIN2K 
    // Fields below this are available in OSes after w2k 
    SET_CONTEXT_ATTRIBUTES_FN_W   SetContextAttributesW; 
#endif // greater thean 2K 

钍切总而言之,这意味着在之间的对象大小的不匹配LIB和这导致运行时检查失败。

Class!

0

您的.lib文件是否与库的.lib链接?我从你的例子中假设你包含了析构函数声明的头文件;没有它,删除这种类型是允许的,但可能导致UB(以一种奇怪的方式违背一般规则,即在使用之前必须定义某些事物)。如果.lib文件没有链接在一起,有可能是自定义的operator delete或析构函数有一些奇怪的链接问题,虽然不应该发生,但你永远无法完全知道它不会。

2

一种可能性是它的calling convention不匹配 - 确保您的库和可执行文件都设置为使用相同的默认调用约定(通常为__cdecl)。要设置,请打开项目属性并转至配置属性> C/C++>高级并查看呼叫公约选项。如果你使用错误的调用约定调用一个函数,你会完全搞砸堆栈。

+0

所有的项目都使用__cdecl。崩溃只发生在创建特定类型的对象时 - 其他对象工作正常。 – Rob 2008-12-12 16:58:02

0

没有看到更多的代码,很难给你一个确定的答案。但是,为了追踪内存覆盖,我推荐使用WinDbg(免费从Microsoft搜索“Debugging Tools for Windows”)。

当你将它连接到你的进程时,你可以让它为内存访问设置断点(读,写或执行)。它总体上非常强大,但它应该特别帮助你。

0

当对象超出范围或被删除时,将引发该错误。

每当我遇到这个问题时,它必须使用与应用程序的其余部分不同版本的C++运行库编译的库。