是否需要将free *()参数转换为void *?

时间:2014-08-16 11:08:43

标签: c malloc free

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

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

np是链接列表中的structdefnchar *

4 个答案:

答案 0 :(得分:5)

C11:7.22.3.3自由功能

  

概要

#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 *;然而,编码器有时可能会同时使用两者并且习惯于总是进行投射(因为除了遵守通用编码指南以避免冗余演员表之外,实际上没有任何缺点)。