删除指针、将其设置为null和释放指针之间有什么区别。
delete ptr;
对比。
ptr=NULL;
vs.
:对比。free(ptr);
根据您的问题,您来自一种具有垃圾收集功能的语言。而C++没有垃圾收集。
如果您将指针设置为NULL,这并不会导致内存返回到可用内存池中。如果没有其他指针指向此内存块,则现在您只有一个“孤立”的内存块仍然被分配,但是现在无法访问 -- 一个泄漏(leak)。只有当内存耗尽时,泄漏才会导致程序崩溃。
还有另一种相反的情况,即您使用指针delete
一个内存块,然后稍后尝试访问该内存,就好像它仍然被分配一样。这是可能的,因为在指针上调用delete
并不会将指针设置为NULL--它仍然指向以前分配的内存地址。指向不再分配的内存的指针称为悬垂指针(dangling pointer),访问它通常会导致奇怪的程序行为和崩溃,因为其内容可能不是您期望的内容 -- 这段内存可能已经为其他目的重新分配了。
[编辑]如stinky472所提到的,delete
和free()
之间的另一个区别是只有前者调用了对象的析构函数。 (请记住,您必须对使用new
分配的对象调用delete
,并对使用malloc()
分配的内存调用free()
-- 它们不能混合使用。) 在C++中,如果可能的话最好使用静态分配,但如果不行,则更喜欢使用new
而不是malloc()
。
realloc()
,它允许移动内存中的项目。在其他情况下,您可以使用放置new
和显式析构函数调用来管理对象生命周期而不会产生UB,尽管这当然有点不方便和容易出错。 - j_random_hackerdelete
将释放已分配的内存给C++运行库。在此之前需要使用匹配的new
在堆上分配内存。NULL
是指向不存在地址的“占位符”。在C++中,NULL
是一个宏定义为0
。因此,如果不喜欢宏,也可以直接使用0
。在C++0x中引入了nullptr
,并被推荐使用。
示例:
int* a; //declare pointer
a = NULL; //point 'a' to NULL to show that pointer is not yet initialized
a = new int; //reserve memory on the heap for int
//... do more stuff with 'a' and the memory it points to
delete a; //release memory
a = NULL; //(depending on your program), you now want to set the pointer back to
// 'NULL' to show, that a is not pointing to anything anymore
如果您使用“new”动态创建对象,则将指针设置为任何值都不会从内存中删除对象,这将导致内存泄漏。
new
获取的对象应该使用delete
进行删除,使用new[]
获取的数组应该使用delete[]
进行删除,使用malloc()
获取的内存应该使用free()
进行释放。然而,在C++中,你不应该使用malloc()
。它所做的是分配动态__内存__,而new
则创建动态分配的__对象__。原则上,new
所做的是通过调用类型的构造函数来分配内存和创建对象。 - sbiint
也被称为“对象”。我认为你的意思是它不一定是一个左值,它也可以是一个右值。 - sbi42
,它只是一个表达式,而是值为42,这是通过计算表达式 42
得出的结果。lvalues和rvalues都是一种表达式,不是对象的一种。int 类型的 lvalue 是产生 int 对象的表达式,而 int 类型的 rvalue 是产生 int 值的表达式。(对于类类型,lvalues 和 rvalues 都会生成对象。)如果你在标准中搜索“对象表示”和“值表示”,你会发现对象和值完全不同。 - fredoverflow当您使用new创建一个对象时,您需要使用delete来释放其内存以返回给系统。这样,该内存将可供其他人重用。
int* a = new int;
delete a;
NULL是一个预定义的宏,可以分配一个指针来表示它不指向任何东西。
int* a = new int;
a = NULL;
int * ptr = null;
调用free(ptr)
将不会有任何作用。根据标准,如果给定的指针为空,则不会发生任何操作。
使用delete p
也将不会有任何作用。C++标准规定,因为它指向空值且没有可用类型,所以不会发生任何操作。
delete
概念,你是指只有C++才有吗? - GManNickGdelete ptr;
和ptr=NULL;
之间再加一个“vs.”,这个问题会更有意义。 - j_random_hacker