将free()参数转换为void * neccessary?
是否有必要将传递给free()
的值转换为此代码段中的void指针?
free((void *) np->defn);
np
是链表中的struct
, defn
是char *
。
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 *
; 然而,编码器有时可能会同时使用两者并且习惯于总是进行投射(因为除了遵守通用编码指南以避免冗余演员表之外,确实没有其他方面)。