C free对通过值传递给函数的指针做了什么?

C free对通过值传递给函数的指针做了什么?,c,pointers,memory-management,C,Pointers,Memory Management,众所周知,如果我们将指针按值传递给函数,它将无法在函数内部释放,如下所示: void func(int *p) { free(p); p = NULL; } p持有一个(可能是有效的)地址的副本,所以free(p)试图释放它。但既然它是拷贝,它就不能真正释放它。对free()的调用如何知道它不能真正释放它 上面的代码不会产生错误。这是否意味着free()只是默默地失败,“不知何故”知道作为参数传入的地址无法处理 p持有一个(可能是有效的)地址的副本,所以free(p)试图释放它

众所周知,如果我们将指针按值传递给函数,它将无法在函数内部释放,如下所示:

void func(int *p)
{
    free(p);
    p = NULL;
}
p持有一个(可能是有效的)地址的副本,所以free(p)试图释放它。但既然它是拷贝,它就不能真正释放它。对free()的调用如何知道它不能真正释放它

上面的代码不会产生错误。这是否意味着free()只是默默地失败,“不知何故”知道作为参数传入的地址无法处理

p持有一个(可能是有效的)地址的副本,所以free(p)试图释放它。但既然它是拷贝,它就不能真正释放它

这不是真的<如果
p
是由
malloc()
(或
NULL
)返回的有效地址,则code>free()可以正常工作

事实上,这是实现自定义“析构函数”函数的常见模式(在用C编写OO风格代码时)

您可能的意思是
p
在此之后不会变为
NULL
,但这是很自然的,因为您是按值传递它的。如果要
free()
清空指针,请通过指针(“byref”)传递它:

像这样使用这个

int *p = someConstructor();
func(&p);
// here 'p' will actually be NULL

不,你真的释放了内存块。函数调用后,传递到此函数的指针不指向任何地方:相同的地址,但MMU不再知道如何处理此地址。唯一的问题是此函数是否位于不同的DLL(Windows)中。然后,它可能与标准库的不同版本相链接,并且对如何构建堆有不同的想法


否则没有问题。

通过值将
p
传递到
func()
,这将复制指针并创建本地副本到
func()
,从而释放内存
func()
然后将它自己的指针实例
p
设置为
NULL
,但这是无用的。函数完成后,参数
p
即告结束。在调用函数时,仍然有指针
p
保存一个地址,但是块现在在空闲列表中,在再次分配之前,对存储没有用处。

大家都说,内存将被
空闲(p)释放,但原始指针(用于调用函数)仍将保留(现在无效)地址。如果包括地址在内的新内存块在稍后阶段分配,则原始指针将再次生效(对于内存管理器),但现在将指向完全不同的数据,从而导致各种问题和混乱。

eh。。。那就行了。当然,传递给函数的指针不会为NULL,但内存将是空闲的'd.StackOverflow经验法则#3:如果OP说“它是已知的”,它不是。内存不会被释放,但要将原始指针设置为NULL,你需要指针本身的地址,而不是指针的副本。你是什么意思,一点也不?哦,但它是-我也解释了原因。不,对不起,它是不正确的。标准库的版本与此无关。您可以多次说“它不正确”,并且不会改变任何内容。请重新阅读我的答案,了解标准库版本的重要性,您将能够避免伤害许多业余爱好者的危险陷阱。
int *p = someConstructor();
func(&p);
// here 'p' will actually be NULL