Brian Blais said:
Hello,
I saw on a couple of recent posts people saying that casting the return
value of malloc is bad, like:
d=(double *) malloc(50*sizeof(double));
why is this bad? I had always thought (perhaps mistakenly) that the
purpose of a void pointer was to cast into a legitimate date type. Is
this wrong? Why, and what is considered to be correct form?
thanks,
You will find folks on both sides of the issue.
The main (some would say *only*) argument against
casting the result is that it will hide the failure
to include <stdlib.h> which declares malloc to return
(void *). The compiler will assume it returns (int),
and casting (int) to (something *) will cause undefined
behavior.
The folks on the other side of the argument say that
their compiler will complain loudly when a function
is referenced without a declaration (implementation-defined behavior), so the
question about including <stdlib.h>
is moot. Once past the question of proper malloc()
declaration, one must contend with the whether the
target pointer is what one intended.
======================
#include <stdlib.h>
static void fubar(void)
{
float * d; /* programmer changed this...! */
/* some dozen lines later in the code */
/* silent erroneous size calculation */
d = malloc(50*sizeof(double));
}
======================
If the programmer decides to change the declaration
of "d", the compiler will *NOT* catch the bad assignment.
If the assignment used a cast (double *), then the
compiler would complain about incompatible pointer
types.
======================
#include <stdlib.h>
static void fubar(void)
{
float * d; /* programmer changed this...! */
/* some dozen lines later in the code */
/* incompatible pointer assignment */
d = (double *) malloc(50*sizeof(double));
}
======================
Another suggestion is *not* to use "sizeof(double)",
but use "sizeof *d", so that the element size changes
automatically when changing the target declaration.
======================
#include <stdlib.h>
static void fubar(void)
{
struct gonk * d; /* programmer changed this...! */
/* some dozen lines later in the code */
/* 50 elements of whatever "d" points to... */
d = malloc(50*sizeof *d);
}
======================
Now the malloc() is compatible with changing the
target type of the pointer variable "d". You can
change it to any kind of pointer type and the
malloc will be compatible. This is the recommended
way to use malloc(), so that:
1. A missing <stdlib.h> is caught.
2. The malloc() assignment is always compatible
with any pointer type.
3. The size calculation changes along with any
change to the target declaration.
If you insist on using sizeof(double) in the size
calculation, then you should cast the result so that
the compiler will complain when the target type is
changed (so that you can change the sizeof() and
recompile). However, you will save yourself some
maintenance headaches by using: "d = malloc(50*sizeof *d);"
2 cents worth. Your mileage may vary.
--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS!
Are ISV upgrade fees too high? Check our custom product development!