ptr为NULL的free(ptr)是否会损坏内存?

Vij*_*jay 106 c free null pointers

从理论上讲,我可以这么说

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

是一个内存损坏,因为我们释放已经释放的内存.

但是如果

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

由于操作系统将以不确定的方式运行,我无法对此进行实际的理论分析.无论我在做什么,这种记忆是否会腐败?

释放空指针有效吗?

Gre*_*osz 212

7.20.3.2 free功能

概要

#include <stdlib.h> 
void free(void *ptr); 
Run Code Online (Sandbox Code Playgroud)

描述

free函数使得指向的空间ptr被释放,即可用于进一步分配.如果ptr是空指针,则不执行任何操作.

ISO-IEC 9899.

话虽这么说,当你在野外查看不同的代码库时,你会注意到人们有时会这样做:

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

这是因为一些C运行时(我肯定记得在PalmOS上就是这种情况)在释放NULL指针时会崩溃.

但是现在,我认为free(NULL)根据标准的指示,假设是一个nop是安全的.

  • 不,ptr = NULL无法替代free(ptr),两者完全不同 (28认同)
  • @WereWolfBoy他的意思是通过在调用`free()之前测试指针`NULL`来避免`free(NULL)` (6认同)
  • 不,这意味着`free(ptr)`其中`ptr`为null没有副作用.但无论如何,使用`malloc()`或`calloc()`分配的每个内存必须在使用`free()之后释放. (5认同)
  • ptr = NULL确保即使您意外地调用free(ptr),您的程序也不会出现段错误. (4认同)
  • 您不需要多次询问您的问题。编辑您的问题帖子并附加您想要的信息。 (2认同)
  • 请注意,虽然C标准说它是无操作,但这并不意味着每个C库都会像这样处理它.我已经看到免费崩溃(NULL),所以最好避免首先调用free. (2认同)

R S*_*hko 21

所有符合标准的C库版本都将free(NULL)视为no-op.

也就是说,曾经有一些版本的免费版本会免费崩溃(NULL),这就是为什么你会看到一些防御性编程技巧的建议:

if (ptr != NULL)
    free(ptr);
Run Code Online (Sandbox Code Playgroud)

  • @Tomas - 我从不建议改变风格,我只是解释了为什么你仍然可以在某些风格中看到这个推荐. (39认同)
  • -1 [需要引证].由于一些陈旧的传闻实现的理论而改变代码风格是一个坏主意. (7认同)
  • @Tomas:问题在于版本7 Unix.当我学习时,free(xyz)其中xyz == NULL是我学习的机器上的即时灾难的一个秘诀(ICL Perq运行PNX,它基于版本7 Unix和一些System III附加功能).但是我很长时间没有用这种方式编码. (7认同)
  • @Tomas 3BSD(http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html)和PalmOS for two(两者都是第二手). (5认同)
  • Netware也因释放NULL而崩溃...(只是调试了崩溃而已...) (2认同)
  • Drepper 自 2012 年起就不再负责 glibc。然而,对于 TR-24731 中字符串函数(缺乏)实用性的看法,很多人都同意他的观点。此外,C11 附件 K (TR-24731) 是可选的,因此 glibc 省略它并不不合规。最后,有严肃的建议从下一个标准中删除附录 K;请参阅提交给 WG14 的 N1967。要求 free(NULL) 为无操作是第一个 ANSI C 1989/ISO C 1990 标准的一部分,因此没有任何 C 运行时符合不支持它的 C 标准的任何版本。 (2认同)

Mic*_*ker 12

如果ptr为NULL,则不执行任何操作.

说文件.

  • 本杰明,这正是它的含义.如果它知道参数的无效性,你会期望它执行什么? (2认同)

小智 10

我记得在PalmOS上工作过free(NULL).

  • 有趣 - 这使得第二个平台(在3BSD之后)崩溃. (3认同)
  • 如果我没记错的话,Palm 上不存在 C 标准库。相反,有一个几乎不受支持的头文件将标准库调用映射到 Palm OS SDK。很多事情都出乎意料。与标准库相比,在“NULL”上崩溃是 Palm 工具箱的最大运行差异之一。 (2认同)

Pra*_*rav 8

free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */
Run Code Online (Sandbox Code Playgroud)

您可以安全地删除NULL指针.在这种情况下不会执行任何操作.换句话说,free()对NULL指针不执行任何操作.


ste*_*anB 8

推荐用法:

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

看到:

man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.
Run Code Online (Sandbox Code Playgroud)

将指针设置为NULL之后free(),可以free()再次调用它并且不执行任何操作.

  • 这也有助于发现调试器的段错误.很明显,p-> do()与p = 0的段错误是使用释放指针的人.在调试器中看到p = 0xbfade12时不太明显:) (3认同)

n0r*_*0rd 6

free(NULL)在C语言中是完全合法的,delete (void *)0并且delete[] (void *)0在C++中是合法的.

顺便说一下,释放内存两次通常会导致某种运行时错误,所以它不会破坏任何东西.

  • 在C ++中,“删除0”是非法的。`delete`明确需要一个指针类型的表达式。将“删除”应用于类型化的空指针值是合法的,但不适用于“ 0”(而不是“ NULL”)。 (2认同)