C++ 跟踪潜在内存覆盖时出现问题。窗户怪诞

C++ 跟踪潜在内存覆盖时出现问题。窗户怪诞,c++,windows,C++,Windows,这让我快发疯了。我在Windows.lib中使用了一些第三方代码,该代码在调试模式下会导致类似以下错误: Run-Time Check Failure #2 - Stack around the variable 'foo' was corrupted. 当对象超出范围或被删除时,将引发错误。只需分配其中一个对象,然后删除它就会抛出错误。因此,我认为问题可能出在许多构造函数/析构函数中的一个,但尽管逐行检查了每一行代码,我还是找不到问题 但是,只有在静态库中创建其中一个对象时才会发生这种情况。

这让我快发疯了。我在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
}
因此,删掉“middle”.lib文件可以解决这个问题,而正是这个weridness让我抓狂。EXE和2个LIB都使用相同的CRT库。链接时没有错误。第三方代码使用继承,共有5个基类。我已经注释了尽可能多的代码,同时仍在构建它,我只是看不出有什么问题


所以,如果有人知道为什么.lib中的代码与.exe中的相同代码会有不同的行为,我很想听听。与跟踪内存覆盖的任何提示相同!我正在使用Visual Studio 2008。

您的.lib文件是否与库的.lib链接?从您的示例中,我假设您正在使用析构函数声明包含头;如果没有它,删除这样的类型是允许的,但可能会以一种奇怪的方式导致UB,这与使用之前必须定义某些内容的一般规则相反。如果.lib文件未链接在一起,则可能是自定义运算符delete或destructor出现了一些奇怪的链接问题,虽然这种情况不应该发生,但您永远无法确定是否会发生。您的.lib文件是否与库的.lib相链接?从您的示例中,我假设您正在使用析构函数声明包含头;如果没有它,删除这样的类型是允许的,但可能会以一种奇怪的方式导致UB,这与使用之前必须定义某些内容的一般规则相反。如果.lib文件未链接在一起,则可能是自定义运算符delete或destructor出现了一些奇怪的链接问题,尽管这种情况不应该发生,你永远无法判断它是否会。一种可能性是它不匹配-确保你的库和可执行文件都设置为使用相同的默认调用约定(通常是cdecl)。要设置它,请打开您的项目属性,进入Configuration properties>C/C++>Advanced并查看调用约定选项。如果您使用错误的调用约定调用函数,您将完全弄乱堆栈。

一种可能是不匹配-请确保您的库和可执行文件都设置为使用相同的默认调用约定(通常是cdecl)。要设置它,请打开您的项目属性,进入Configuration properties>C/C++>Advanced并查看调用约定选项。如果您使用错误的调用约定调用函数,您将完全打乱堆栈。

如果看不到更多代码,很难给出确切的答案。但是,为了跟踪内存覆盖情况,我建议使用Microsoft提供的WinDbg免费搜索


当您将它连接到进程时,您可以让它为内存访问的读、写或执行设置断点。总体来说,它确实很强大,但它应该特别有助于您解决这个问题。

如果没有看到更多的代码,很难给您一个明确的答案。但是,为了跟踪内存覆盖情况,我建议使用Microsoft提供的WinDbg免费搜索

当您将它连接到进程时,您可以让它为内存访问的读、写或执行设置断点。总体来说,它确实很强大,但它应该特别有助于您实现这一点

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

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

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


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

< P> OK,我跟踪问题,如果有人感兴趣,它是一个破解程序。基本上是my.LIB,它显示了这个问题。已将_WIN32_WINNT定义为0x0501 Windows 2000及更高版本,但我的EXE和第三方库将其定义为0x0600 Vista。现在,第三方库中包含的一个头文件是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之间的对象大小不匹配,这导致了 e运行时检查失败


上课

好的,我找到了问题所在,如果有人感兴趣的话,这是个难题。基本上是my.LIB,它显示了这个问题。已将_WIN32_WINNT定义为0x0501 Windows 2000及更高版本,但我的EXE和第三方库将其定义为0x0600 Vista。现在,第三方库中包含的一个头文件是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之间的对象大小不匹配,这导致了运行时检查失败


上课

所有项目都在使用cdecl。只有在创建特定类型的对象时才会发生崩溃-其他对象工作正常。好吧,这只是猜测-如果没有更多信息,很难从心理上调试其他人的问题。感谢指针Adam。这个问题快把我逼疯了。我几乎要放弃第三方代码而尝试其他东西了。所有的项目都在使用cdecl。只有在创建特定类型的对象时才会发生崩溃-其他对象工作正常。好吧,这只是猜测-如果没有更多信息,很难从心理上调试其他人的问题。感谢指针Adam。这个问题快把我逼疯了。我几乎要放弃第三方代码而尝试其他东西了。