C语言中带参数的free()语法

15

我正在将许多Unix的C程序转换到Linux上,而这个free()语法引起了我的注意:

free((char *) area );

这个和 free( area ); 有什么区别呢?

3个回答

17

free 的签名为:

void free(void *ptr);

那么如果area是由malloc或其类似函数返回的指针类型,那么在free((char *) area );中的转换是无意义的。

除非......如果代码真的非常古老,也就是在ANSI C引入void *作为通用指针之前。在那个古老的时代,char *被用作通用指针。


1
实际上,这段代码有些陈旧,大约是1990年左右编写的,针对那个时代的老式Unix系统。area是一个在结构体成员中声明为int类型的指针。谢谢。 - user3772839

15
如果有人将指向动态分配数据的指针存储在标准认可的非指针类型中,例如将 area 声明为 intptr_t,这将把非指针类型转换为指针类型并允许释放它。
如果 area 已经是指针类型,则任何在过去25年内编写的C代码都不会出现这种情况。

是的,对于面积确实是这样。谢谢! - user3772839

0

free()在标准中的签名是错误的。它应该是void free(const void *);才能真正正确。这意味着当你想要释放一个const *时,必须将其上转型而不会收到警告。

这里有Linus Torvald关于为什么free()应该采用const *的抱怨。

编辑:争议的根本想法源于一般人认为const对指针所指向的内存有任何影响,即指针指向只读内存。这显然是错误的。 const限定符是指针的属性,而不是它所指向的东西。这是一个重要的区别。


3
我对此并不信服。malloc返回的是非const类型,所以你需要在mallocfree之间进行强制类型转换。其次,const表示一种合同,意味着您不会修改内存指针指向的内容。释放该内存将违反该约定。我无法想出任何支持它的论点,因此我会对支持const的论点感兴趣。 - MicroVirus
2
@MicroVirus:免费并不是修改内容,而是彻底抹除它的存在。 - Zan Lynx
7
这个答案是错误的,Linus 也是错误的。语义上,如果你规定不允许通过指向一个已分配对象的指针 p 修改该对象,则 free(p) 违反了该规定:结束对象的生命周期是一种(严重的!)修改。 - R.. GitHub STOP HELPING ICE
1
@hvd 我同意 R.. 的观点。Linus的论点是基于实现而非纯语言,他的结尾句子充满了高傲自大的味道。这表明“如果你不按照我的方式看待问题,那么我比你聪明多了,而你只是个笨蛋”。在调用 free 后没有对象存在,因此没有有效的对象可以进行比较。他的发泄只是如此而已,我不会因为来源而过分解读他的发泄。我认识一个叫 Sutter 的人,他认为 VC++ 是最好的 C++ 编译器。对啊,只是因为你聪明并不意味着你是正确的。 - WhozCraig
1
@WhozCraig 你说得对,仅仅因为是Linus提出的论点并不意味着它自动成立,但也没有人声称它是这样的。 :) 我想到的一件事是 { const int a = 0; }。这是明确定义的,但会结束一个被定义为“const”的对象的生命周期。修改一个被定义为“const”的对象是不允许的,所以这个块能够有效的唯一方式就是结束一个对象的生命周期不算作修改。 - user743382
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接