c++ - Visual Studio 2008 - vftable 指针不正确? Debug模式崩溃,Release没问题

标签 c++ visual-studio debugging crash release

我目前正面临 VS08 的问题。我得到了以下(简化的)类结构:

class CBase
{
    public:
    virtual void Func() = 0;
};

class CDerived : public CBase
{
public:
    void Func();
};

此代码在 Release模式下运行良好,但当我尝试运行调试构建时,它立即在 new CDerived 处崩溃。

进一步分析让我找到了崩溃的位置。它在 CBase::CBase(编译器生成的构造函数)处崩溃。更准确地说,它在 04AE46C6 mov dword ptr [eax],offset CBase::vftable' (505C2CCh) `处崩溃。

有什么线索吗? Release模式很好,但我无法正确调试它。

最佳答案

Release Mode is fine

不,看起来还不错。我的猜测是在调试中内存以某种方式被覆盖。由于无法仅根据您发布的代码来判断,因此您可以执行以下操作。

我假设你在某处创建对象:

CBase* p = new CDerived;

或类似的。在 Debug模式下,在 p 的位置设置一个内存断点。您可以将其设置为监视 4 个字节。 Visual C++(像大多数编译器一样)会将 vfptr 保持为类中的第一件事,因此该断点将跟踪该位置是否被覆盖。如果在您调用崩溃的函数之前命中断点,那就是您的问题(并且调用堆栈会告诉您它被覆盖的原因)。

这可能有很多原因——你可能会溢出一些内存并覆盖对象(如 Erik 所建议的)——发布版本可能会直接解析调用以防止动态调度的开销,这可以解释为什么它不是崩溃。

也可能是您在对象上调用了 delete 并且调试版本实际上将内存归零,而发布版本则没有。仅凭这一点无法判断。

关于c++ - Visual Studio 2008 - vftable 指针不正确? Debug模式崩溃,Release没问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14863150/

相关文章:

c++ - C++ 中的双引号字符串

c++ - 如何从 switch 语句中排除浮点值?

linux - 为什么 x86 汇编函数的 GDB 断点设置在错误的地址?

c++ - 如何调试垃圾堆/没有.dmp/用户的机器

c++ - 我在 C++ 中的方法有问题

具有隔离键/值的 C++ 缓存友好 HashMap

c# - 用于验证 string.Format 方法的 Visual Studio 加载项

windows - 恢复 Azure Web 角色网站?

c# - 似乎无法在 c# 中使用 XmlSerializer 反序列化非常简单的 xml

visual-studio - 您最喜欢在 Visual Studio 中调试程序的方式是什么?