删除指针,将其设置为null并释放它之间有什么区别。
delete ptr;
VS。
ptr=NULL;
VS
free(ptr);
答案 0 :(得分:49)
您的问题表明您来自一种垃圾收集语言。 C ++没有垃圾收集。
如果将指针设置为NULL,则不会导致内存返回可用内存池。如果没有其他指针指向这个内存块,你现在只需要一个“孤立”的内存块,它仍然被分配但现在无法访问 - 泄漏。泄漏只会导致程序崩溃,如果它们构建到没有内存分配的点。
还有相反的情况,你使用指针delete
一块内存,然后尝试访问该内存,就像它仍然被分配一样。这是可能的,因为在指针上调用delete
不会将指针设置为NULL - 它仍然指向先前分配的内存地址。指向不再分配的内存的指针称为悬空指针,访问它通常会导致奇怪的程序行为和崩溃,因为它的内容可能不是你所期望的 - 那块内存可能有因为被重新分配用于其他目的。
[编辑] 正如stinky472所提到的,delete
和free()
之间的另一个区别是只有前者调用对象的析构函数。 (请记住,必须对分配有delete
的对象调用new
,对free()
分配的内存调用malloc()
- 它们不能混用。)在C ++中,如果可能,最好使用静态分配,但如果没有,则更喜欢new
到malloc()
。
答案 1 :(得分:27)
delete
将分配的内存返回给C ++运行时库。你总是需要一个匹配的new
,它之前在堆上分配了内存。 NULL
是完全不同的东西。一个“占位符”,表示它指向没有地址。在C ++中,NULL
是一个定义为0
的MACRO。因此,如果不喜欢MACROS,也可以直接使用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
答案 2 :(得分:5)
好吧,如果您动态创建对象(使用'new'),设置指向任何值的指针不会从内存中删除对象 - 并且会出现内存泄漏。
答案 3 :(得分:4)
与任何间接一样,使用指针时会涉及两个对象: referrer (示例中的指针{{1 }}和 引用的对象 (它指向的是ptr
)。你需要学会区分它们。
当您将*ptr
分配给指针时, 仅指针受影响 ,它所引用的对象将保持不变。如果指针是指向该对象的最后一个指针,则您丢失了指向它的最后一个引用指针,因此不再使用它。但是,在C ++中, 并不意味着该对象将被删除 。 C ++没有垃圾收集。因此,对象 泄露 。
要删除对象,您必须将其地址(存储在指针中)传递给NULL
运算符 手动删除 。如果您这样做, 只会影响 引用的对象,指针将保持不变。它仍然可能指向对象驻留在内存中的地址,即使它不再可用。这称为 悬空指针 。
答案 4 :(得分:2)
使用new创建对象时,需要使用delete将其内存释放回系统。然后,内存将可供其他人重用。
int* a = new int;
delete a;
NULL只是一个预定义的宏,可以指定一个指针,表示它不指向任何东西。
int* a = new int;
a = NULL;
在上面的例子中,在为a分配存储空间后,您将为其分配NULL。但是,先前为a分配的内存未释放,系统无法重用。这就是我们所说的内存泄漏。
答案 5 :(得分:1)
int * ptr = null;
致电free(ptr)
将不会做任何事情。根据标准,如果给定的指针为null,则不会发生任何动作。
使用delete p
也不会做任何事情。 C ++标准表示不会发生任何操作,因为它指向任何内容并且没有类型可用。