I have the following C code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
#define ARRAYSIZEWITHPTR(a) (&(a)[1] - a)
int main (void){
int array[5] = {1,2,3,4,5};
int* pArray = array;
int* p = calloc(ARRAYSIZE(array), sizeof(int));
assert(NULL != p);
printf("size of array: %ld\n", ARRAYSIZE(array));
printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
printf("size of p: %ld\n", ARRAYSIZE(p));
printf("size of pArray: %ld\n", ARRAYSIZEWITHPTR(pArray));
printf("size of p: %ld\n", ARRAYSIZEWITHPTR(p));
free(p);
return 0;
}
When I compile this program, I get the following warning messages from gcc:
test.c: In function ‘main’:
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
| ^
test.c:15:35: note: in expansion of macro ‘ARRAYSIZE’
15 | printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
| ^~~~~~~~~
test.c:11:8: note: first ‘sizeof’ operand was declared here
11 | int* pArray = array;
| ^~~~~~
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
| ^
test.c:16:30: note: in expansion of macro ‘ARRAYSIZE’
16 | printf("size of p: %ld\n", ARRAYSIZE(p));
| ^~~~~~~~~
test.c:12:8: note: first ‘sizeof’ operand was declared here
12 | int* p = calloc(ARRAYSIZE(array), sizeof(int));
| ^
And the following is the program output:
size of array: 5
size of pArray: 2
size of p: 2
size of pArray: 1
size of p: 1
As is evident from the program output, I get the correct value only when the macro is invoked with the array name as the argument. However, isn't array name the pointer to the first element of the array? If so, what is the quintessential difference between invoking the macro with the array name (which yields the correct result) a opposed to the pointer pointing to an array on the heap (which doesn't yield the correct result?)
As can be seen from the source code, I have tried both the macro approaches to get the size of the array created on the heap, without success.
So the next question is, is it possible at all to get the size of the array created thus on the heap using calloc(
) in C programming?
TIA
There is no standardized way to find out how much allocated memory a pointer returned from malloc
/calloc
/realloc
points to. The programmer is expected to keep track of that himself.
In your example, since p
and pArray
have type int *
sizeof(p)
and sizeof(pArray)
are giving you the size of the type int *
which is most likely 8 on your system.
However, isn't array name the pointer to the first element of the array?
No, an array name is an array, however in most contexts the array decays to a pointer to its first element. One of the cases where this does not happen is when the array is the operand of the sizeof
operator, So since array
has array type, sizeof(array)
gives you the size of the entire array.