CS Student
CS Student

Reputation: 1633

Is casting free() argument to void * neccessary?

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

Answers (4)

kdopen
kdopen

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

M.M
M.M

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

N. Erkamp
N. Erkamp

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

haccks
haccks

Reputation: 106052

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);

Upvotes: 7

Related Questions