lichgo
lichgo

Reputation: 533

char *data = "abc"; free( (void*)data ); Why void* conversion? Is it necessary?

There is a C-style string and I need to free the memory of it. I saw the following code sample but got confused about why (void*) is there.

char *data = "abc";
free( (void*)data );

Just two questions:

  1. Why not simply free(data)?

  2. Is (void*) conversion is a must?

Many thanks.

Upvotes: 0

Views: 382

Answers (4)

David Ranieri
David Ranieri

Reputation: 41017

Is an error to call free() since is not allocated using (m/c/re)alloc.

As pointed out by Jens Gustedt, a cast is only needed when you pass a const pointer because free() takes a void *, not a const void *:

const int *x = malloc(sizeof(int));

free((void *)x);

Without a cast you get:

demo.c:8:5: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [enabled by default] In file included from demo.c:2:0: /usr/include/stdlib.h:488:13: note: expected ‘void *’ but argument is of type ‘const int *’

Upvotes: 3

unwind
unwind

Reputation: 399891

No, it's not necessary; the free() call is wrong and you cannot do this.

The cast is a huge blinking, bouncing, and screaming warning flag that the originating programmer was confused.

It's undefined behavior to pass a pointer not returned by a previous call to malloc() or one of its friends to free(). The cast is the least of the problems here.

You can never "free" the memory used by a string literal, since that memory is never allocated in some way that the program controls. It's not on the heap, and the heap is where dynamic memory allocation/deallocation typically happens. Your intention is wrong.

All you can do is set the pointer to NULL:

data = NULL;

that will not in any way "free" the memory used behind the scenes to hold the character data "abc" though, but that's fine.

Upvotes: 6

Mats Petersson
Mats Petersson

Reputation: 129374

So, your premise here is incorrect, you do not need to free your "data" at all, it will most likely cause a crash if you do. You should only call free for data that has come from malloc, and "abc" is not one of those.

Second, if you are using C, then you should do:

char *data = malloc(4);
strcpy(data, "abc");
...
free(data);

In C++ we also can't convert a void * [the return value from malloc] to char *, so you would need char *data = (char *) malloc(4);, but free(data) should still work. Some compilers may issue warnings for this, and the standard MISRA, for example, does not allow ANY automatic conversions of C types, so explicit casts are REQUIRED here [not because the language says so, but because the MISRA standard does, and there are "checking software" that reads the source code to check these sort of criteria are met].

Of course, in "fresh"[1] C++, we should not use malloc or free, but new and delete:

char *data = new char[4];
strcpy(data, "abc");
....
delete [] data;

[1] As in "code written as C++ from scratch".

Upvotes: 0

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29213

The cast is unnecessary. In C, a void* is implicitly convertible to and from other pointer types. free expects a void*, so no cast is required from another pointer type.

(Of course, as already pointed out, the code is obviously problematic altogether, so don't read into it too much.)

Upvotes: 0

Related Questions