Search code examples
arrayscpointersdouble-pointer

C - Double pointer array - not getting correct values


Context

I created this simple code where I store various arrays in my_arrays() function and different functions (in my example the main()) can get the hard-coded arrays via the function my_arrays().

See the code here:

#include <stdio.h>

int my_arrays(int *size, int **arrays) {
    size[0] = 3;
    int array_1[3] = {1, 2, 3};
    arrays[0] = array_1;

    size[1] = 5;
    int array_2[5] = {2, 3, -5, 7, 11};
    arrays[1] = array_2;
}


int main() {
    int num_of_arrays = 2;
    int sizes[2];
    int *arrays[2];
    my_arrays(sizes, arrays);

    for (int i=0; i < num_of_arrays; i++) {
        int *array = arrays[i]; // point to sub-array
        int size = sizes[i];

        printf("array[%d]: {", i);
        for (int x=0; x < size; x++) {
            printf(" %d", array[x]);
        }
        printf(" }\n", i);
    }
    return 0;
}

In the main() I then loop through the sub-arrays and loop through each individual number and print it out.

What I expect the code above to print out is:

array[0]: { 1 2 3 }
array[1]: { 2 3 -5 7 11 }

But when compiling and running I get this:

array[0]: { 1993067712 1617605192 -2 }
array[1]: { 3936256 8 6422188 7 6422476 }

Why?


Solution

  • In my_arrays, array_1 and array_2 are local arrays on the stack. They will be invalid as soon as you return from my_array. Now arrays[0] and arrays[1] hold pointers to invalid or "stale" memory. Accessing that is undefined behaviour.

    (The garbage values you see shows you that your arrays have been overwritten by other uses of the stack space, probably by calls to printf.)

    If you want to create arrays, you can allocate memory on the heap:

    int my_arrays(int *size, int **arrays)
    {
        size[0] = 3;
        arrays[0] = malloc(3 * sizeof(int));
        
        arrays[0][0] = 1;
        arrays[0][1] = 2;
        arrays[0][2] = 3;
    
        // ... initialize other arrays ...
        
        return 0;
    }
    

    You should explicitly free it after you're done using it:

    // at the end of main
    
    for (int i=0; i < num_of_arrays; i++) {
        free(arrays[i]);
    }