是否有必要将传递给free()
的值转换为此代码段中的void指针?
free((void *) np->defn);
np
是链接列表中的struct
,defn
是char *
。
答案 0 :(得分:5)
概要
#include <stdlib.h> 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);
答案 1 :(得分:2)
从技术上讲,您不需要转换为(void *)
。
有人在评论中询问是否有任何编译器在没有演员的情况下发出警告,并得到了响应&#34;一个破坏的,可能&#34;。
嗯,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.
添加演员表并没有什么害处,并且避免了禁用该警告的诱惑 - 从而错过了一个真正的错误。
答案 2 :(得分:0)
不,不是。虽然这样做可能会防止编译器发出警告错误。
free(void *);
函数free
将释放任何使用malloc分配的内存。它所需要的只是malloc
返回的内存地址。因此,只要np->defn
具有malloc返回的内存值,就应该没问题。
答案 3 :(得分:0)
这取决于具体情况。如果未包含stdlib.h
,并且我们处于C89模式,则必须进行强制转换。这是因为:在调用范围内没有原型的函数时,参数类型(在默认参数提升之后)必须与函数实现的实际参数类型匹配。
当然,更好的解决方案是包含stdlib.h
,并确保启用编译器诊断程序以提醒您,以防您在没有原型范围的情况下调用free
。
在K&amp; R天(甚至第2版)中,通常的做法是在没有原型的范围内调用函数。
到目前为止,在任何答案中都没有提到的另一点是人们有时会使用const T *
来拥有一个动态分配内存的拥有指针。例如,如果np->defn
的类型为const int *
,则必须抛弃const
,即使包含stdlib.h
也是如此。并且转换为void *
是实现这一目标的简单方法。
这是因为free
的原型是void free(void *ptr);
而C不允许隐式转换从指针后面删除const
。
您确实在问题中指明它是非const char *
;然而,编码器有时可能会同时使用两者并且习惯于总是进行投射(因为除了遵守通用编码指南以避免冗余演员表之外,实际上没有任何缺点)。