关于C++:虚拟方法与MSVC的碰撞

Virtual method crash with MSVC

我想我在MSVC的编译器中发现了一个bug(MSVC Ultimate 2012版本11.0.61030.00更新4)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include"stdafx.h"

class Base
{
public:
    Base()
    {
    }

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

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

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

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

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

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;
}

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

思想?


5.3.5/3 In the first alternative (delete object), if the static type of the object to be deleted is different from its
dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the
static type shall have a virtual destructor or the behavior is undefined.

强调我的。碰撞是未定义行为的一种可能表现。""没有什么不好的事情发生"是另一回事。


该问题在不调用"print"函数的情况下发生,并且可以通过向每个类添加虚拟析构函数来解决。


至于我,它看起来像个虫子。我的意思是,如果你在谈论这个,调用以crash结尾的print函数。