在c ++中删除vs NULL vs free

时间:2010-05-26 06:34:34

标签: c++ c

删除指针,将其设置为null并释放它之间有什么区别。

delete ptr;

VS。

ptr=NULL;

VS

free(ptr);

6 个答案:

答案 0 :(得分:49)

您的问题表明您来自一种垃圾收集语言。 C ++没有垃圾收集。

如果将指针设置为NULL,则不会导致内存返回可用内存池。如果没有其他指针指向这个内存块,你现在只需要一个“孤立”的内存块,它仍然被分配但现在无法访问 - 泄漏。泄漏只会导致程序崩溃,如果它们构建到没有内存分配的点。

还有相反的情况,你使用指针delete一块内存,然后尝试访问该内存,就像它仍然被分配一样。这是可能的,因为在指针上调用delete不会将指针设置为NULL - 它仍然指向先前分配的内存地址。指向不再分配的内存的指针称为悬空指针,访问它通常会导致奇怪的程序行为和崩溃,因为它的内容可能不是你所期望的 - 那块内存可能有因为被重新分配用于其他目的。

[编辑] 正如stinky472所提到的,deletefree()之间的另一个区别是只有前者调用对象的析构函数。 (请记住,必须对分配有delete的对象调用new,对free()分配的内存调用malloc() - 它们不能混用。)在C ++中,如果可能,最好使用静态分配,但如果没有,则更喜欢newmalloc()

答案 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 ++标准表示不会发生任何操作,因为它指向任何内容并且没有类型可用。