Reputation: 1633
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 *
.
Upvotes: 4
Views: 4905
Reputation: 8215
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.
Upvotes: 2
Reputation: 141618
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 without any 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 second 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).
Upvotes: 3
Reputation: 26
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.
Upvotes: 1
Reputation: 106052
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);
Upvotes: 7