C++ 调用delete后的指针无效

C++ 调用delete后的指针无效,c++,invalid-pointer,C++,Invalid Pointer,我在一个名为virtual.cpp的文件中有这个简单的代码: #include <iostream> class Parent { public: virtual ~Parent(){ std::cout << "Parent Destructor" << std::endl; } virtual void VirtualFunction() { std::cout << &

我在一个名为
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;

}

但当我运行它时,我得到了以下错误:

./virtual 
Child Destructor
Parent Destructor
free(): invalid pointer
Annullato (core dump creato)
我想这是因为我删除了指针parent1,所以这会删除指针指向的内存,即
&child1
。 因此,当child1超出作用域时,子析构函数将尝试释放不再存在的内存

我的问题:

  • 我的推理正确吗
  • 如果我的推理是正确的,那么处理这种“超出范围”的情况的正确方法是什么

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

    如果希望对象在作用域内开始其生存期,并在作用域结束时结束其生存期,请不要使用
    new
    delete
    。正常申报即可

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

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

    否。您将从删除中获得一个核心转储

    只有从
    new
    返回的地址才能传递到
    delete

    delete
    不会擦除内存,因为内存没有“已擦除”状态的概念

    处理这种“超出范围”的情况的正确方法是什么

    删除
    delete
    行。这是没有必要的


    范围内创建的任何变量在离开该范围时都会自动管理。

    首先,您不使用
    new
    或任何其他方式来分配动态内存。因此,没有必要使用
    删除


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

    要更具体地回答您的问题

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

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

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

    删除
    您的
    新建
    。由于
    新建父类,您会遇到同样的问题,并且内存泄漏
    的地址被覆盖并丢失。@现在您已经得到了一些答案,我不建议您使用此空间询问新问题。如果您需要,这里有一个[询问问题]按钮。@vaexecutes--关键字
    delete
    并不意味着“擦除”。它的目的是通知分配器,以前使用
    new
    分配的内存现在可以重用(如有必要)。事实上,没有什么东西会被“擦除”。可能发生的情况是,调试运行时将在区域上写入一个值,但这就是“擦除”的范围。您将发现,如果不知道并使用正确的术语,很难与程序员讨论编程。我无法正确管理术语,感谢您指出。我的意思是delete释放了parent1指向的内存。是否正确?@vaexecuis
    delete
    将调用指向的对象的析构函数,然后释放或释放内存。是的。我只是在使用虚拟函数,通常调用
    parent1->VirtualFunction()
    和动态绑定(希望我使用了正确的术语)。代码的其余部分不存在,因为它不是问题的一部分。
    Parent * parent1 = new(Child);
    delete(parent1);