Need assistance in understanding this code using malloc and pointers
Here is a little snippet of code from Wikipedia's article on malloc():
int *ptr;
ptr = malloc(10 * sizeof (*ptr)); // Without a cast
ptr = (int*)malloc(10 * sizeof (int)); // With a cast
I was wondering if someone could help me understand what is going on here. So, from what I know, it seems like this is what's happening:
1) initialize an integer pointer that points to NULL. It is a pointer so its size is 4-bytes. Dereferencing this pointer will return the value NULL.
2) Since C all开发者_JS百科ows for this type of automatic casting, it is safe not to include a cast-to-int-pointer. I am having trouble deciphering what exactly is being fed into the malloc function though (and why). It seems like we are getting the size of the dereferenced value of ptr. But isn't this NULL? So the size of NULL is 0, right? And why are we multiplying by 10??
3) The last line is just the same thing as above, except that a cast is explicitly declared. (cast from void pointer to int pointer).
I'm assuming we're talking about C here. The answer is different for C++.
1) is entirely off. ptr
is a pointer to an int
, that's all. It's uninitialized, so it has no deterministic value. Dereferencing it is undefined behaviour -- you will most certainly not get 0 out! The pointer also will most likely not point to 0. The size of ptr
is sizeof(ptr)
, or sizeof(int*)
; nothing else. (At best you know that this is no larger than sizeof(void*)
.)
2/3) In C, never cast the result of malloc: int * p = malloc(sizeof(int) * 10);
. The code allocates enough memory for 10 integers, i.e. 10 times the size of a single integer; the return value of the call is a pointer to that memory.
The first line declares a pointer to an integer, but doesn't initialize it -- so it points at some random piece of memory, probably invalid. The size of ptr
is whatever size pointers to int
are, likely either 4 or 8 bytes. The size of what it points at, which you'd get by dereferencing it when it points somewhere valid, is whatever size an int
has.
The second line allocates enough memory for 10 int
s from the heap, then assigns it to ptr
. No cast is used, but the void *
returned by malloc()
is automatically converted to whatever type of pointer is needed when assigned. The sizeof (*ptr)
gives the size of the dereferenced ptr
, i.e. the size of what ptr
points to (an int
). For sizeof
, it doesn't matter whether ptr
actually points to a valid memory, just what the type would be.
The third line is just like the second, but with two changes: It explicitly casts the void *
return from malloc()
to an int *
, to match the type of ptr
; and it uses sizeof
with the type name int
rather than an expression of that type, like *ptr
. The explicit cast is not necessary, and some people strongly oppose its use, but in the end it comes down to preference.
After either of the malloc()
s ptr
should point to a valid location on the heap and can be dereferenced safely, as long as malloc
was successful.
For line 2 malloc() is allocating enough memory to hold 10 pointers.
malloc() is a general purpose function void so it must be cast to whatever type you actually want to use, in the above example pointer to int.
精彩评论