I am curious why I am getting the following behaviour in my code.
int main(int argc, char *argv)
int* ptr=(int*) malloc(sizeof(int)*N); /*Allocate memory of size N */
printf("Size of your malloced array is %lu\n",sizeof(ptr)/sizeof(ptr)); /* Get the size of memory alloctaed. Should be the same as N?*/
printf ("Size of your normal arrays is %lu\n",sizeof(arr)/sizeof(arr)); /* Ditto */
The output is
Size of your malloced array is 2
Size of your normal arrays is 24
I would have thought the output would be
24 in both places. How then does one get the size of the malloced array If somehow I have “forgotten” it?
Surely the pointer
ptr will contain some information about the size of the malloced array since when we call
free(ptr) it will release the array just malloced
When you use
sizeof() on a pointer, you get the size of the pointer. Not the size of the allocated array. In your case, a pointer is probably 8 bytes and an
int is 4 bytes, hence why you get 2.
In short, you can’t get the size of an allocated array. You need to keep track of it yourself.
EDIT : Note that some compilers do actually support this functionality as an extension:
For example, MSVC supports
sizeof() works as you’d expect with fixed-length and variable-length arrays, it doesn’t know anything about the sizes of
When applied to a pointer,
sizeof() simply returns the size of the pointer.
More generally, given a pointer to a
malloc()‘ed block, there’s no standard way to discover the size of that block.
See C FAQ questions 7.27 and 7.28.
In summary, if you need to know the size of a heap-allocated array in a portable manner, you have to keep track of that size yourself.
You cannot obtain, at runtime, the size of an array if you only have a pointer to (the first element of) the array. There are no constructs at all in C that allow you to do this. You have to keep track of the length yourself.
If you happen to have an array rather than a pointer then you can find its length, but not for a pointer to an element of the array.
In your code,
ptr is a pointer and so you cannot find out the length of the array to which it points. On the other hand,
arr is an array and so you can find out its length with
As this other question points out, there is no portable way getting the size of a dynamic array, since
malloc may allocate more memory than requested. Furthermore managing malloc requests is up to the operating system. For instance *nix would calls
sbrkand store the requests somewhere. So, when you call
sizeof(ptr) it returns the size of the pointer and not the size of the array. On the other hand, if your array is fixed, the size of it is determined at compile time, so the compiler is able to replace
sizeof(arr) with the size of the fixed array, thus providing you the “correct” size.
The size of a pointer is 4 bytes on 32-bit machines and 8 bytes on 64-bit machines. I guess you work on a 64-bit machine since the size of an int is 4, and you got that
sizeof(ptr)/sizeof(ptr) is 2.
The thing to remember about
sizeof is that it is a compile-time operator1; it returns the number of bytes based on the type of the operand.
The type of
int , so
sizeof arr will evaluate to the number of bytes required to store 24
int values. The type of
int *, so
sizeof ptr will evaluate to the number of bytes required to store a single
int * value. Since this happens at compile time, there’s no way for
sizeof to know what block of memory
ptr is pointing to or how large it is.
In general, you cannot determine how large a chunk of memory a pointer points to based on the pointer value itself; that information must be tracked separately.
Stylistic nit: a preferred way to write the
malloc call is
int *ptr = malloc(sizeof *ptr * N);
In C, you do not need to cast the result of
malloc to the target pointer type2, and doing so can potentially mask a useful diagnostic if you forget to include
stdlib.h or otherwise don’t have a prototype for
malloc in scope.
Secondly, notice that I pass the expression
*ptr as the operand to
sizeof rather than
(int). This minimizes bugs in the event you change the type of
ptr but forget to change the type in the corresponding
malloc call. This works because
sizeof doesn’t attempt to evaluate the operand (meaning it doesn’t attempt to dereference
ptr); it only computes its type.
1 The exception to this rule occurs when
sizeof is applied to a variable-length array; since the size of the array isn’t determined until runtime, a
sizeof operator applied to a VLA will be evaluated at runtime.
2 Note that this is not the case in C++; a cast is required, but if you’re writing C++ you should be using
delete instead of
free anyway. Also, this is only true since C89; older versions of C had
char * instead of
void *, so for those versions the cast was required. Unless you are working on a very old implementation (such as an old VAX mini running an ancient version of VMS), this shouldn’t be an issue.