调用删除后的指针无效



我在一个名为virtual.cpp:的文件中有这个简单的代码

#include <iostream>

class Parent
{
public:
virtual ~Parent(){ std::cout << "Parent Destructor" << std::endl; }
virtual void VirtualFunction()
{
std::cout << "VirtualFunctionInParent" << std::endl;
}
};
class Child: public Parent
{
public:
virtual ~Child() { std::cout << "Child Destructor" << std::endl; }
virtual void VirtualFunction()
{
std::cout << "VirtualFunctionInChild" << std::endl;
}    
};
int main()
{
Child child1;
Parent *parent1 = &child1;
delete parent1;
}

它正确编译

g++ -Wall --pedantic -o virtual virtual.cpp 

但当我运行它时,我得到了这个错误:

./virtual 
Child Destructor
Parent Destructor
free(): invalid pointer
Annullato (core dump creato)

我认为这是因为我删除了指针parent1,所以这会擦除指针指向的内存,即&child1。因此,当child1超出作用域时,Child析构函数会尝试释放已不存在的内存。

我的问题:

  1. 我的推理正确吗
  2. 如果我的推理是正确的,那就是处理这个问题的正确方法;超出范围";情况

我删除了指针parent1,因此这会擦除指针指向的内存。我的推理正确吗?

否。您正在从您的删除中获得一个核心转储。

只有从new返回的地址可以被传递到delete

delete擦除存储器,因为存储器没有"擦除"的概念;擦除";状态

这是处理这个问题的正确方法"超出范围";情况

删除delete行。没有必要。

在一个范围内创建的任何变量都会在该范围保留时自动进行管理。

不要对未使用new分配的对象调用delete。当这个对象超出范围时,它会被删除,所以没有什么特别的事情可以正确地销毁它。

当您希望对象在作用域内开始其生存期,并在作用域结束时结束其生存期时,不要使用newdelete。正常申报即可。

对要管理其生存期的对象使用newdelete。将它们分配给new,并在完成后调用delete

首先,您不使用new或任何其他方式来分配动态内存。因此,使用delete是没有意义的。

要回答您的下一个问题,您必须首先告诉我们为什么要在孩子的地址上创建父指针?

更具体地回答您的问题

  1. 我的推理正确吗

您永远不会超出范围,因为您正在main((中向当前堆栈帧声明变量。为了向堆声明变量(超出范围(,必须使用动态内存分配。

Parent * parent1 = new(Child);
delete(parent1);

这段代码所做的是在堆中创建一个子类,然后在有效指向该子类的作用域的本地创建parent1指针。

最新更新