为什么不将free(p)设置为NULL?

Ole*_*aev 15 c c++ free memory-leaks memory-management

任何原因导致这不能成为标准行为free()

多个指针指向同一个对象:

#include <stdlib.h>
#include <stdio.h>

void safefree(void*& p)
{
    free(p); p = NULL;
}

int main()
{
    int *p = (int *)malloc(sizeof(int));
    *p = 1234;
    int*& p2 = p;
    printf("p=%p p2=%p\n", p, p2);
    safefree((void*&)p2);
    printf("p=%p p2=%p\n", p, p2);
    safefree((void*&)p); // safe

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

来自malloc要求的转让void*

反之亦然:

safefree()要求转向void*&(参考)

小智 28

如果是,则必须将指针传递给指向函数的指针:

int * p = malloc( sizeof( int ));
free( & p );
Run Code Online (Sandbox Code Playgroud)

我相信很多人会出错.

  • 这当然加上当然很多次p只会是一个局部堆栈变量,在这种情况下,只要它超出范围,将其设置为NULL就变得无关紧要了.此外,如果存在对同一内存块的多个引用,那么如果其中一个是免费的,它们将不会全部设置为NULL,因此它实际上没有多大帮助. (10认同)
  • `void**`是**不是**指针类型的通用指针.`void**`是指向特定对象类型的指针:`void*`.如果`void**'指针指向一个实际的`void*`,它只能被解除引用. (2认同)

Mar*_*tos 27

简单的回答:因为你可能正在释放一个表达,例如free(find_named_object("foo")).

更详细:该free函数接受一个void*参数,该参数是要释放的内存的地址.这并不赋予函数对提供地址的原始变量的任何知识(或者,就此而言,是否存在变量).只是将传入的参数设置为NULL也不会做任何事情,因为它只是地址的本地副本.

  • @Vijay:我认为"表达"@Marcelo的意思是"rvalue".+1最佳答案,BTW. (3认同)
  • 将表达式传递给free应该不是一个原因,因为在C表达式中不是第一类对象.在您的示例中,表达式返回一个指针,该指针又传递给free. (2认同)
  • @Vijay,我不明白你的观点.该表达式确实返回一个指针,然后将其传递给free.那么,如何将'p`设置为NULL?没有'p`可以设置. (2认同)

Ash*_*ain 15

Bjarne Stroustrup 讨论delete运算符是否应该将其操作数归零.它不是free()函数,但无论如何它都是一个很好的讨论.考虑以下几点:

  • 如果你说免费(p + 1)会被归零吗?
  • 如果内存有两个指针怎么办?如果仍然留下悬空引用,为什么只将一个设置为null?

他还说这是有意的,但从未发生过operator delete:

C++显然允许delete的实现将左值操作数归零,我曾希望实现会这样做,但这个想法似乎并没有受到实现者的欢迎.


Fer*_*cio 6

C函数参数总是按值传递,因此为了修改传递给free()的指针,您需要将指针传递给被释放的指针,这可能会导致忘记&运算符导致的错误.

其次,如果该指针有任何别名,程序员仍然负责将它们归零.我可以看到程序员假设所有引用都设置为NULL而导致的问题.

最后,并不总是需要将指针设置为NULL.想象一个函数,它分配一些内存,做一些工作并在返回之前释放它.我可以看到如何将指针设置为NULL似乎不是最佳的.


use*_*291 5

因为函数参数是用C中的值传递的.也就是说,如果p == 0x12345,则将'0x12345'传递给free(),而不是p"本身".