Flash said:
The cast [on malloc's return value] is *not* required.
Yes, it is not required is C, but C++ does require it. besides the cast
cant harm anyone, unless its being incorrectly cast!
If you are writing C++ code, you should not be using malloc() at all
(you should be using container classes and/or "new"). It is generally
unwise to compile code intended as C using a C++ compiler, as the
semantics may change unexpectedly:
#include <stdio.h>
struct S { char a[1]; };
int main(void) {
struct T { struct S { char a[1000]; } a; };
printf("sizeof(struct S) = %lu\n", (unsigned long)sizeof(struct S));
return 0;
}
(Exercise: what is the most likely output of the above, as both
C and C++? Why is it different?)
In any case, in my experience here in comp.lang.c (since it was
net.lang.c back in 1983 or so), I find that code that contains a
cast usually does so *because* it is being "incorrectly cast".
(In particular, the use of a cast is a strong hint that the programmer
has failed to "#include <stdlib.h>". This was not true in 1983,
(This is my favorite version as well.)
That does make some sense, but what if ptr is of type 'void *'?
Yes, as Lawrence Kirby noted, in that case, the call cannot follow
the pattern. Of course, if "ptr" is declared as "void *", the
appropriate size for the malloc() call has to be supplied separately:
/* like malloc, but print error message and exit on failure */
void *emalloc(size_t size) {
void *p = malloc(size);
if (p == NULL) {
panic("out of memory");
/* NOTREACHED */
}
return p;
}
There are cases where I drop the "N *" part, when I know I want
one object:
struct S *p;
...
p = malloc(sizeof *p);
Of course, 1 * x == x, for all integral x, in C.
There is another case for which I drop the "sizeof *ptr", when
"ptr" points to (plain) char:
char *dupstr(char *orig) {
char *s;
size_t len = strlen(orig) + 1; /* +1 to account for '\0' */
s = malloc(len);
if (s != NULL) /* or maybe use emalloc() */
memcpy(s, orig, len);
return s;
}
because sizeof(char) == 1 (by definition). I feel reasonably safe
in this case, because if someone decides to change "char" to some
internal "wider character" type, the strlen() call will also become
incorrect, and the dupstr() function as a whole will need rework,
not just the type of "s".
I agree. seg faults are specific to some OSs. But if p=NULL, and then
you do a p->func(), no matter what the OS, it is a runtime error, dont
you think?
This depends on how you define "runtime error". There are machines
on which this turns out to be a recursive call to main(). (In C,
main() may be called recursively, unlike C++. This is another
reason not to attempt to compile C code with a C++ compiler.
)