Search code examples
arrayscmallocpointer-arithmetic

Why are the addresses of malloced 2D array not what I expect?


With the aim of allocating memory for a 2D array in C I run

double (*t)[2] = malloc(sizeof(*t)*4);

I expected this to allocate 64 bytes (4 times the size of two doubles). That is, I expected t[0] and t[1] to have room for 4 doubles each. For this reason, I thought that the address of t[0] and t[1] should be separated by 32 bytes. However, I find that they are separated by 16 bytes (corresponding to only two doubles).

printf("Address of t[0]: %p\n", t[0]);  // Address of t[0]: 00C92490
printf("Address of t[1]: %p\n", t[1]);  // Address of t[1]: 00C924A0

What am I missing here?


Solution

  • It seems to be a misunderstanding in the declaration and the allocation here. You declare t to be an array, where each element in the array t is an array of two double elements. Then you allocate enough space for four elements in t.

    Your definition and allocation is equivalent to:

    double t[4][2];
    

    If you want to create an array of two elements, where each element is a dynamically allocated array, you need an array of pointers instead:

    double *t[2] = { malloc(sizeof(*t[0]) * 4), NULL };
    

    The above define t as an array of two elements, each elements is a pointer to a double, and you initialize the first element (t[0]) to point to an array of four double elements, and the second (t[1]) to be a null pointer.


    The important part is the difference between

    double (*t)[2];`
    

    and

    double *t[2];
    

    Using the clockwise/spiral rule the first defines t as "a pointer to an array of two double". The second defines t as "an array of two pointers to double".