【问题标题】:Assertion error attempting to delete base pointer to derived object尝试删除指向派生对象的基指针的断言错误
【发布时间】:2019-01-22 20:03:23
【问题描述】:

在研究 C++ 中的继承时,我了解到用于多态行为的基类应将其析构函数实现为 virtual

我以为我理解如何很好地应用这个,但是我遇到了一个我不明白的小问题。

给定以下代码:

#include <iostream>

struct Base
{
    Base() { std::cout << "Base ctor called\n"; };
    virtual ~Base() { std::cout << "Base dtor called\n"; };
};

struct Derived : Base
{
    Derived() : Base() { std::cout << "Derived ctor called\n"; }
    ~Derived() { std::cout << "Derived dtor called\n"; };
};

int main()
{
    Derived d;
    Base *p_base = &d;

    delete p_base; //Problem here?

    return 0;
}

输出如预期:

Base ctor called
Derived ctor called
Derived dtor called
Base dtor called

但是,出现_CrtisValidHeapPointer(block) 断言错误。

如果p_base 直接指向一个新的Derived 对象,即Base *p_base = new Derived();,则一切正常

这里有什么不同?

亲切的问候

【问题讨论】:

  • deleteing 自动分配的内存会调用未定义的行为。每个new 一个delete,不多了;不少。
  • 所有新闻都应该与删除相匹配。你不能没有另一个。
  • 密切相关/重复Is it possible to delete a non-new object?。 TL;DR:您可以删除指向自动分配的指针,但程序将无法安然无恙。
  • 您只能使用delete 使用new 创建的对象。

标签: c++ polymorphism


【解决方案1】:

问题是您的本地构造对象d 将在其范围结束时被自动删除,在您的情况下,当您调用return 0 时。但是那个时候,你已经删除了指向同一个对象的p_base。因此该对象被删除了两次。

您的问题与继承无关。即使是同一类的对象,它也应该出现。

【讨论】:

  • 谢谢。我是否正确假设 p_base 也会同时被删除,所以我不必担心悬空指针?
  • p_base 不会被删除,也不应该被删除。当范围结束时,p_base 不再存在。这与释放动态内存不同。
  • @Jake 你可能把你的术语弄混了。悬空指针是指所指向的内容从指针下方消失,从而使指针指向无效内存时发生的情况。有时因为这是因为指针被分配了一个随后超出范围的自动变量。您似乎担心内存泄漏。自动存储不能泄露。编译器会确保这一点。
猜你喜欢
  • 2012-02-05
  • 1970-01-01
  • 2011-11-04
  • 2021-12-03
  • 1970-01-01
  • 2014-06-16
  • 2021-05-20
  • 2011-11-04
相关资源
最近更新 更多