Why is malloc allocated array shows less size than static allocated array

112 Views Asked by At

Why is arr1 size less than arr2, am I missing something? Does it have to do something with malloc and stack, heap?

#include <malloc.h>
#include <stdio.h>

int main(void)
{
    int length = 4;
    int *arr1 = (int*)malloc(length*sizeof(int));

    int arr2[length];
    arr2[0] = 10;
    arr2[1] = 20;
    arr2[2] = 30;
    arr2[3] = 40;

    arr1 = arr2;

    for (int i = 0; i<length; printf("%d\n", arr1[i++])) ;

    printf("Size of arr %lu\n", sizeof(arr1));
    printf("Size of arr2 %lu\n", sizeof(arr2));
    printf("Size of int %lu", sizeof(int));    
}

Output:

$ gcc -g new.cpp && ./a.out
10
20
30
40
Size of arr 8
Size of arr2 16
Size of int 4

I was expecting to have arr1 and arr2 both have 16 byte size.

3

There are 3 best solutions below

0
Vlad from Moscow On BEST ANSWER

The variable arr1 declared like

 int *arr1 = (int*)malloc(length*sizeof(int));

has the pointer type int * while the variable arr2 declared as a variable length array

int arr2[length];

has the type int[4].

So the expression sizeof( arr1 ) that is equivalent to sizeof( int * ) yields the size of the pointer itself.

Pay attention to that your program has a memory leak because a memory was allocated and its address was stored in the pointer arr1 and then the pointer arr1 was reassigned

arr1 = arr2;

The array arr2 used as an expression in the above assignment statement is implicitly converted to a pointer to its first element. That is the above statement in fact is equivalent to

arr1 = &arr[0];

Also to output a value of the type size_t you should use conversion specification %zu because the C Standard accepts that it is not necessary that the type unsigned long is an alias for the type size_t..

From the C Standard (7.19 Common definitions <stddef.h>)

4 The types used for size_t and ptrdiff_t should not have an integer conversion rank greater than that of signed long int unless the implementation supports objects large enough to make this necessary

Also if you wil write for example sizeof( arr2 + 0 ) then again the expression will yield the size of a pointer because in this expression arr2 + 0 with the pointer arithmetic the array arr2 is implicitly converted to a pointer to its first element.

0
user12002570 On

First things first int arr2[length] is not standard C++. Some compilers allow it as an extension.


Now coming to the question, arr1 is a pointer to an int(an int*) while arr2 is a array of type int(int [4]). This means that:

sizeof(arr1) gives you the number of bytes the pointer arr1 occupies while sizeof(arr2) gives you the number of bytes the array occupies. In your case an int is occupying 4 bytes and so the array occupies 16 bytes. OTOH, in your case, int* is occupying 8 bytes.

sizeof(arr1) //same as sizeof(int*)
sizeof(arr2) //same as sizeof(int [4])
0
463035818_is_not_an_ai On

sizeof(arr1) is the same as sizeof(int*) while sizeof(arr2) is the same as sizeof(int[4]).

In other words, arr1 is a pointer to int, while arr2 is an array of 4 ints. They are of different type and those types occupy different amount of bytes.

arr1 does point to the first element of an array, but that does not make it an array. The actual size of the two arrays in your program is the same.