虚拟方法与MSVC崩溃

时间:2014-02-03 22:09:00

标签: c++ visual-c++ compiler-construction crash

我想我在MSVC的编译器中发现了一个错误(MSVC Ultimate 2012 Version 11.0.61030.00 Update 4)。

#include "stdafx.h"

class Base
{
public:
    Base()
    {
    }

    void print()
    {
        printf("Base::print()\n");
    }
};

class Derived : public Base
{
public:
    Derived() : Base()
    {
    }

    virtual void print()
    {
        printf("Derived::print()\n");
    }
};

class DerivedSquared : public Derived
{
public:
    DerivedSquared() : Derived()
    {
    }

    void print()
    {
        printf("DerivedSquared::print()\n");
    }
};

int main(int argc, char *argv[])
{
    Base *obj1 = new Base();
    Base *obj2 = new Derived();
    Base *obj3 = new DerivedSquared();

    obj1->print();
    obj2->print();
    obj3->print();

    // Memory leaks are ALWAYS nasty :P
    delete obj1;

    // CRASH!!!
    // File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
    //  _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
    delete obj2;
    delete obj3;

    return 0;
}

该代码的特殊性在于Base的printf()方法不是虚拟的,而Derived的是。 GCC不会发生这种情况(我已用codepad测试过)。 我想知道这是否是一个真正的编译器错误,或者我错过了一些明显的东西。

思想?

3 个答案:

答案 0 :(得分:4)

  

5.3.5 / 3 在第一个备选方案(删除对象)中,如果要删除的对象的静态类型与其不同   动态类型,静态类型应该是要删除的对象的动态类型的基类   静态类型应具有虚拟析构函数或行为未定义

强调我的。崩溃是未定义行为的一种可能表现。 "似乎没有发生任何不良事件"是另一个。

答案 1 :(得分:2)

问题出现时没有调用'print'函数,可以通过向每个类添加一个虚析构函数来解决。

答案 2 :(得分:0)

至于我,那看起来像个bug。我的意思是如果您正在谈论这个问题,则调用以崩溃结束的打印功能。