tags:

views:

312

answers:

6
    int length = strlen(src);
    char *structSpace = malloc(sizeof(String) + length + 1);
    String *string = (String*) structSpace;    
    int *string = (int*) structSpace;

*I created a struct called String

+6  A: 

Because malloc returns a pointer to void, i.e., it is simply allocating chunks of memory with no regard as to the data that will be stored there. In C++ your returned void* will not be implicitly cast to the pointer of your type. In your example, you have not cast what malloc has returned. Malloc returned a void* which was implicitly cast to a char*, but on the next line you... ok, it doesn't make much sense anymore.

Ed Swangren
oops! what about now?
Now your code doesn't make sense. Two variables called `string`? What are you really trying to ask?
Carl Norum
To be clear, you do not have to and shouldn't really cast the return value of `malloc()` in the C programming language. This is related to an old problem that was an issue before C90. I think the original question might have been tagged as C++ and not C, for which the behavior is different as the answerer stated.
BobbyShaftoe
+11  A: 

You don't. void* will implicitly cast to whatever you need in C. See also the C FAQ on why you would wnat to explicitly avoid casting malloc's return in C. Sinan's answer further illustrates why this has been followed inconsistently.

Andrew Coleson
+1. C++ is a different story, however.
Carl Norum
Correct, you shouldn't be using malloc in C++.
Andrew Coleson
This is the typical response, but I don't completely agree. Sure, if you have a braindead compiler it might let you get away without including `stdlib.h`, but there are some cases where you can let the compiler check your work. See my comment on http://stackoverflow.com/questions/1322884/does-going-out-of-scope-like-this-free-the-associated-memory/1322898#1322898
Andrew Keeton
+6  A: 

The C FAQ list is an invaluable resource: Why does some code carefully cast the values returned by malloc to the pointer type being allocated?.

Sinan Ünür
+2  A: 

This is one of the few issues that makes the statement "C++ is a superset of C" not completely true. In C, a void pointer can be implicitly cast to any other type of pointer. However, C++ is a bit more strict with type safety, so you need to explicitly cast the return value of malloc to the appropriate type. Usually, this isn't much of an issue, because C++ code tends to use new rather than malloc, which doesn't require typecasting.

Charles Salvia
+2  A: 

In C, casting the result from malloc is unnecessary and should not be done. Doing so can, for example, cover up the error of having failed to #include <stdlib.h>, so you don't have a prototype for malloc in scope. This, in turn, can lead to other errors and lack of portability (though the worst offenders in that respect are now mostly obsolete).

In C++, you must cast the result of malloc to assign it to a pointer to any type other than void. Unless you really need to write code that can be compiled as either C or C++, however, you should generally avoid using malloc in C++ at all and allocate memory using new.

Jerry Coffin
+1  A: 

You tend to see this kind of C code from novices (or C++ coders :-) ):

int main() {
    int len = 40;
    char *my_string = (char *) malloc(sizeof(char)*len);
    return 0;
}

This is unnecessary and evil, you can avoid the useless cast via including stdlib.h

#include <stdlib.h>
int main() {
    int len = 40;
    char *my_string = malloc(sizeof(char)*len);
    return 0;
}
Vinko Vrsalovic
If you really want a `sizeof` use `char *my_string = malloc(sizeof(*my_string)*len);` so that the RHS remains correct even if the LHS changes. Otherwise, note that `sizeof(char)` is always `1`.
Sinan Ünür
BTW, if you don't #include <stdlib.h>, the code is incorrect, because malloc() without prototype returns an int, and pointer values might not be representable by an int (undefined behavior...)
jpalecek