Is casting free() argument to void * neccessary?

[亡魂溺海] 提交于 2019-12-02 04:25:03

问题


Is it neccessary to cast the value passed to free() to a void pointer in this code snippet?

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

np is a struct in a linked list and defn is a char *.


回答1:


C11 : 7.22.3.3 The free function

Synopsis

#include <stdlib.h>
void free(void *ptr);  

It means that it can take pointer to any type (void * is a generic pointer type). In general no need to cast the argument to void *, but in cases like

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

compiler will generate 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 *);
       ^

To suppress this warning a cast is needed

 free((void *)a);



回答2:


Technically, you should not need to cast to (void *).

Someone asked in a comment if any compiler gave a warning in the absence of the cast, and got the response "a broken one, perhaps".

Well, gcc 4.8.4 seems to be broken in that case

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

Compiler version:

$ 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.

It causes no harm to add the cast, and avoids the temptation to disable that warning -- and thus miss a real bug.




回答3:


No it is not. Though doing so will probably prevent warning errors given by your compiler.

free(void *);

The function free will free any memory that is allocated with malloc. All it needs for that is the memory address returned by malloc. So as long as np->defn has a memory value that was returned by malloc you should be fine.




回答4:


It depends on the context. If stdlib.h has NOT been included, and we are in C89 mode, then the cast is necessary. This is because: when calling a function with no prototype in scope, the argument types (after default argument promotion) must match the actual parameter types of the function implementation.

Of course, a better solution is to include stdlib.h, and ensure that compiler diagnostics are enabled to alert you in case you call free without a prototype in scope.

In the K&R days (even 2nd edition) it was still common practice to call functions without a prototype in scope.


Another point, not mentioned in any answer so far, is that people sometimes use const T * to hold an owning pointer to dynamically allocated memory. If np->defn had the type const int *, for example, then it is necessary to cast away the const, even if stdlib.h was included. And casting to void * is a simple way to achieve that.

This is because the prototype for free is void free(void *ptr); and C does not permit implicit conversions to remove const from behind a pointer.

You did specify in the question that it was non-const char *; however the coder might sometimes use both and be in the habit of always casting (since there is really no down-side other than obeying general coding guidelines to avoid redundant casts).



来源:https://stackoverflow.com/questions/25339569/is-casting-free-argument-to-void-neccessary

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!