如何正确删除C++中的指针? 我是C++新手,我有个问题。

如何正确删除C++中的指针? 我是C++新手,我有个问题。,c++,pointers,destructor,C++,Pointers,Destructor,假设您使用以下代码声明了变量x: MyClass *x = new MyClass(); 使用此变量后,我不再需要它 在下列主张中,什么是首选的行动方案,有什么区别 呼叫freex 调用x->~MyClass 调用MyClass::~MyClassp 调用delete x 有人能帮我理解这一点吗 提前感谢。应使用delete关键字删除动态分配给新关键字的变量。new和delete调用指定类的构造函数和析构函数。这意味着您的实例已正确初始化和取消初始化 因此,实例x初始化为MyClass*x=新

假设您使用以下代码声明了变量x:

MyClass *x = new MyClass();
使用此变量后,我不再需要它

在下列主张中,什么是首选的行动方案,有什么区别

呼叫freex

调用x->~MyClass

调用MyClass::~MyClassp

调用delete x

有人能帮我理解这一点吗


提前感谢。

应使用delete关键字删除动态分配给新关键字的变量。new和delete调用指定类的构造函数和析构函数。这意味着您的实例已正确初始化和取消初始化

因此,实例x初始化为MyClass*x=新的MyClass;应使用delete x;删除

然而,如果可能的话,最好在堆栈上声明变量,比如MyClass x;让我们做它的工作。请看以下示例:

{ //在堆栈上创建对象“x” MyClass x; //用“x”做点什么 //一旦对象超出范围,它就会自动被销毁 }

此外,如果您仍然需要动态分配,则现代C++建议使用智能指针,例如和。智能指针自动代替您处理内存。换句话说,通过使用智能指针,您不需要关心删除使用新指针创建的对象。你可以这样写:

{ //在堆上创建对象“x” //正在调用它的默认构造函数 std::shared_ptr x=std::make_shared; //一旦对象超出范围,即使已分配 //在堆上,这里不需要调用“delete”,因为 //删除由“std::shared\u ptr”自动处理 } 如果通过“新建”创建实例:

您必须通过“删除”将其删除:

一,。呼叫freex

否。释放只释放内存,不调用析构函数。如果你的Maloc内存需要释放它,但是在C++中使用MALLC和在从新获得的指针上调用空闲是很少见的。 二,。调用x->~MyClass

不,显式调用析构函数几乎总是错误的

例如,当您通过placement new创建对象时,您不会直接调用delete,而是调用析构函数,因为placement new会在已分配的内存中创建对象

三,。调用MyClass::~MyClassp

不,这没有意义,析构函数不带参数

四,。调用delete x

销毁以前由新表达式分配的对象并释放获得的内存区域

但您不应该手动管理内存。要么依靠自动存储:

MyClass x;
x的Destructor在超出范围时自动调用。或者,如果您确实需要动态内存分配,请使用

进一步阅读: 顺便说一句,这是一个常见的误解,我记得每次谈到Stroustrup都有一个使用new创建对象的示例,然后他解释说它绝对不应该使用new。事实上,这不仅仅是忘记调用delete。考虑:

 { 
     MyClass *x = new MyClass();
     foo();   
     delete x;   // phew I didnt forget to call delete
 }
如果foo抛出异常,那么该代码将泄漏内存。正确的方法是依靠RAII:

 { 
     MyClass x;
     foo();   
 }

现在,如果foo抛出异常,将调用x的析构函数

变量create with new应与DELETE一起删除首选的操作过程是不写入MyClass*x=new MyClass;首先,但是我的x类;如果确实需要动态分配,请使用std::make_unique作为创建指针的默认方式!你根本不用新的。而是使用std::unique_ptr var=std::make_unique@RamblinRose这不是一个复制品,它是关于放置的。请注意,RAII的重要一点是,无论发生什么情况,x都会被销毁,还有,当有一个expetion或return时,如果作用域始终保留在},那么实际使用new和delete就不会那么关键了。刚刚意识到,一旦对象超出范围,你的//就意味着你总是将范围保留在},因为我最后给出了一个与你类似的例子。无论如何,你有我的+1,@idclev463035818是的,谢谢你指出这一点。无论如何,你也有我的+1。我同意删除部分。其次,在我的公司里,通常让这个指针指向0,例如删除x;x=0@dejoma巧合的是,我最近回答了一个关于这个的问题。将指针设置为nullptr用途有限,但其主要效果是错误的安全感。请参见此处:。它不能解决使用new和delete manuallyNext时出现的一般问题。除此之外,在我的公司里,通常都是让这个指针指向0——我只知道一个原因可以解释为什么它会有任何影响——0指针表示需要分配对象。如果它是这样使用的:如果ptr!=nullptr删除ptr;可以完全删除对nullptr的检查,因为
空ptr是完全有效的。如果使用它是因为您的程序流经历了太多的曲折,以至于您不知道指针的状态,那么可能需要检查代码。。。您必须通过delete删除它-除非您使用placement new,然后根本不使用delete,您必须直接调用类型的析构函数ala 2instead@RemyLebeau谢谢,加了一张便条。我认为如果。。。您必须仍然很好,因为它引用了OPs代码
 { 
     MyClass *x = new MyClass();
     foo();   
     delete x;   // phew I didnt forget to call delete
 }
 { 
     MyClass x;
     foo();   
 }