将free()参数转换为void * neccessary?

是否有必要将传递给free()的值转换为此代码段中的void指针?

 free((void *) np->defn); 

np是链表中的structdefnchar *

C11:7.22.3.3自由function

概要

 #include  void free(void *ptr); 

这意味着它可以将指针指向任何类型( void *是通用指针类型)。 通常不需要将参数强制转换为void * ,但是在类似的情况下

 int const *a = malloc(sizeof(int)); free(a); 

编译器会生成一个waring

 test.c: In function 'main': test.c:33:7: warning: passing argument 1 of 'free' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] free(a); ^ In file included from test.c:2:0: /usr/include/stdlib.h:151:7: note: expected 'void *' but argument is of type 'const int *' void free(void *); ^ 

要禁止此警告,需要进行强制转换

  free((void *)a); 

从技术上讲,您不需要转换为(void *)

有人在评论中询问是否有任何编译器在没有演员的情况下发出警告,并且得到的答案“可能是一个破碎的”。

那么,在这种情况下, gcc 4.8.4似乎被打破了

 usr/include/stdlib.h:483:13: note: expected 'void *' but argument is of type 'const char *' extern void free (void *__ptr) __THROW; 

编译器版本:

 $ gcc --version gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

添加演员阵容不会造成任何伤害,并且避免了禁用该警告的诱惑 – 从而错过了一个真正的错误。

不它不是。 虽然这样做可能会防止编译器发出警告错误。

 free(void *); 

free函数将释放任何使用malloc分配的内存。 它需要的只是malloc返回的内存地址。 因此,只要np->defn具有malloc返回的内存值,您应该没问题。

这取决于具体情况。 如果没有包含stdlib.h ,并且我们处于C89模式,则必须进行强制转换。 这是因为:在调用范围内没有原型的函数时,参数类型(在默认参数提升之后)必须与函数实现的实际参数类型匹配。

当然,更好的解决方案是包含stdlib.h ,并确保启用编译器诊断程序以提醒您,以防您在没有原型范围的情况下调用free

在K&R时代(甚至是第2版),通常的做法是在没有原型范围的情况下调用函数。


到目前为止,在任何答案中都没有提到的另一点是人们有时使用const T *来保存一个动态分配内存的拥有指针。 例如,如果np->defn的类型为const int * ,则必须抛弃const ,即使包含stdlib.h也是如此。 铸造void *是实现这一目标的简单方法。

这是因为free的原型是void free(void *ptr); 和C不允许隐式转换从指针后面删除const

你确实在问题中指明它是非const char * ; 然而,编码器有时可能会同时使用两者并且习惯于总是进行投射(因为除了遵守通用编码指南以避免冗余演员表之外,确实没有其他方面)。