-5


I observed some unexpected behavior with the delete semantics. For example, using the following C++ code:

class Base{
    public:
         Base(int tmp) : x(tmp) {}
         ~Base() { std::cout << "Inside Base::~Base()" << std::endl; }
         void foo() { std::cout << "Inside Base::foo()" << std::endl; }
         int x;
};
...
int main(int argc, char** argv)
{
    Base* b = new Base(10);
    delete b;
    b->foo(); 
    std::cout << "b->x: " << b->x << std::endl;
}

I received the following output from Visual Studio 2008:

Inside Base::~Base()
Inside Base::foo()
b->x: 2359492

Why after the call to delete b, I am still able to call the Base::foo() method?

Thanks, Chris

4

3 回答 3

2

正如其他人已经在评论中指出的那样,这是未定义的行为。这意味着实现可以为所欲为,包括返回您期望的值。

它还可能决定格式化您的硬盘驱动器或让著名的恶魔飞出您的鼻子。

有关调用 UB 可能发生的情况的一些轶事,请参阅此问题

于 2013-09-09T15:22:16.443 回答
2

为什么在调用 to 之后delete b,我仍然可以调用该Base::foo()方法?

因为,与所有未定义的行为一样,程序不需要优雅地失败。

在这种情况下,不能保证已删除的内存变得不可访问;即使是这样,调用非虚拟成员函数也不太可能访问该内存。因此,除非程序在调用成员函数之前专门检查对象是否有效(这将非常昂贵,因此默认情况下没有实现会这样做),否则很有可能会按预期调用该函数并隐藏错误。

于 2013-09-09T15:35:27.750 回答
1

删除某些内容后,它会被heap. 这意味着如果您在删除旧信息后没有立即访问它,则无法保证您的旧信息会在那里。人们说不要访问它的原因是因为您无法控制它可能是什么。这种类型的乱码输出是删除变量后“预期的”未定义行为。

正如@LuchianGrigore 所说,“不要这样做”!!!!!!

于 2013-09-09T15:16:29.483 回答