在c ++中删除vs NULL vs free

her*_*ero 37 c c++

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

delete ptr;
Run Code Online (Sandbox Code Playgroud)

ptr=NULL;
Run Code Online (Sandbox Code Playgroud)

free(ptr);
Run Code Online (Sandbox Code Playgroud)

j_r*_*ker 54

您的问题表明您来自具有垃圾收集的语言. C++没有垃圾收集.

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

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

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

  • FTR,这个答案是对问题的第1版的回答:"删除指针并将其设置为NULL有什么区别?" (2认同)

Luc*_*cas 30

delete将分配的内存返回给C++运行时库.你总是需要一个匹配new,它之前在堆上分配了内存.NULL是完全不同的东西.一个"占位符",表示它指向没有地址.在C++中,NULLMACRO定义为0.所以如果不喜欢MACROS,0也可以直接使用.在C++ nullptr中引入了0x 并且更可取.

例:

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
Run Code Online (Sandbox Code Playgroud)

  • 实际上,您将它返回给C++运行时库,它可能会也可能不会将它返回给C运行时库或操作系统. (4认同)
  • 从技术上讲,您将它返回给C运行时库,然后可能会或可能不会将其返回给操作系统. (2认同)

for*_*ret 5

好吧,如果您动态创建对象(使用'new'),设置指向任何值的指针不会从内存中删除对象 - 并且您会收到内存泄漏.


sbi*_*sbi 5

与任何间接调用一样,使用指针时涉及两个对象引用程序(在您的示例中为指针ptr)和被引用的对象(它指向的对象*ptr)。您需要学习区分它们。

当您分配NULL给一个指针时,只有该指针会受影响,它所指向的对象将被保留。如果指针是指向该对象的最后一个指针,则您丢失了指向该对象的最后一个引用指针,因此无法再使用它。但是,在C ++中,这并不意味着该对象将被删除。C ++没有垃圾回收。因此对象泄漏

为了删除对象,您必须通过将其地址(存储在指针中)传递给操作员来手动删除它们delete。如果执行此操作,则会影响所引用的对象,而指针将被保留。它可能仍指向对象在内存中的地址,即使该地址不再可用。那就是所谓的悬空指针