Search code examples
cmultidimensional-arraymemset

Proper use of memset with dynamically allocated multidimensional arrays


At each iteration of a loop I wish to zero all elements in a dynamically defined multidimensional array.

void my_function(int window_size, int row_size){

        double **window_arr;
        window_arr = (double **)calloc((window_size * 2), sizeof(double*));
            for (i = 0; i < (window_size * 2); ++i){
                window_arr[i] = (double*)calloc(3, sizeof(double));
            }
        for (i = 0; i < row_size; ++i){
           ...
           memset(window_arr, 0, sizeof(window_arr) * (window_size * 2) * 3);
        }
    }

This seg faults. Setting a break point before the first memset, but after allocation, looks good.

(gdb) p window_arr[1]
$1 = (double *) 0x22604f50
(gdb) p window_arr[1][0]
$2 = 0
(gdb) q

The break point after the memset

(gdb) p snp_window_arr[1]
$1 = (double *) 0x0
(gdb) p window_arr[1][0]
Cannot access memory at address 0x0
(gdb) q

I have figured out how to use memset for 1d arrays; I would really like to learn how to use memset in the above-described scenario.


Solution

  • You're building an array of pointers to arrays, rather than a single 2D array. That means you have an array of pointers, and each pointer points to a 1D array. Then you try to memset() the entire 2D space, but this is impossible because it is not contiguously allocated.

    You should consider allocating a single array with space for all your elements at once, since your logical 2D array is rectangular anyway. Just do this:

    double *window_arr = calloc((window_size * 2) * 3, sizeof(double));
    

    Then:

    memset(window_arr, 0, (window_size * 2) * 3);
    

    Of course you will then index into this 2D array as window_arr[x*window_size*2 + y] or similar, rather than window_arr[x][y].