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指向的内存。是否正确?@vaexecuisdelete
将调用指向的对象的析构函数,然后释放或释放内存。是的。我只是在使用虚拟函数,通常调用parent1->VirtualFunction()
和动态绑定(希望我使用了正确的术语)。代码的其余部分不存在,因为它不是问题的一部分。
Parent * parent1 = new(Child);
delete(parent1);