In C you can cast the void pointer returned by malloc
. C does this for you but you can also be explicit.
malloc
returns a void *
or void pointer, this returned value can then be cast by a programmer into other pointer types. Or the programmer can rely on C to do the type conversion. C's type conversion using casts is not expected to change.
However, C code that relies on the C-compiler can be obstuse and difficult to read.
A development programmer can help maintenance programmers who will eventually have to read the code.
Adding an explicit cast to the returned value of malloc
helps humans who will have
to read the code and determine the author's intent. This is the real benefit of explicitely casting the void pointer returned by malloc
. This programming practice does
NOT mis-direct the compiler or make use of some arcane compiler feature that might change.
The following three examples highlight this programming practice. In the first example,
malloc
(which is defined in <stdlib.h>
) is explicitely cast and some trivial work is
performed.
#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
In this second example, the only difference is that <stdlib.h>
is commented out. The
code still runs and produces the same result. Now, the "why" of why this works is fairly direct. When C does NOT find the prototype for a function it assumes that the function returns an int
, but malloc
returns a void pointer. In this case the explicit cast has told the C compiler, as well as the source's carbon unit, that the value returned by malloc
should be converted into a character pointer.
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
The final (yeah) example does NOT issue the cast and does not include <stdlib.h>
. Both the Eclipse editor and the compiler complain about this code (as they should). The compiler message is
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
And the source code is:
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// compiler displays a "warning" and prints abc at the console
}
Changing example 3 to include results in no warnings and the program runs as intended. However, both examples 2 and 3 lack the explicit cast and over the lifetime of code written in this style such code will be more expensive and more likely to be changed incorrectly by humans (thus the additional expense) than explicit using casts which are supported by C-compilers.