2D Dynamic Array Allocation and Passing by Reference in C

c, dynamic-memory-allocation, multidimensional-array, pass-by-reference, segmentation-fault

Solution

One set of problems is here:

void allocateMatrix(float ***m) {
    int i;
    m = malloc(2*sizeof(float*));
    for (i = 0; i < 2; i++) {
        m[i] = malloc(2*sizeof(float));
    }
    return;
}

You need to assign to `*m` to get the information back to the calling code, and also you will need to allocate to `(*m)[i]` in the loop.

void allocateMatrix(float ***m)
{
    *m = malloc(2*sizeof(float*));
    for (int i = 0; i < 2; i++)
        (*m)[i] = malloc(2*sizeof(float));
}

There's at least a chance that the other functions are OK. The `fillMatrix()` is written and invoked correctly, though it could be simplified by losing the third `*` from the pointer:

void fillMatrix(float **m)
{
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 2; j++)
            m[i][j] = 1.0;        
    }
}

It might be advisable to pass the triple-pointer to `freeMatrix()` so that you can zero the pointer in the calling function:

void freeMatrix(float ***m)
{
    for (int i = 0; i < 2; i++)
        free((*m)[i]);
    free(*m);
    *m = 0;
}

Calling then becomes:

allocateMatrix(&matrix);
fillMatrix(matrix);
freeMatrix(&matrix);   

Problem

Can someone wiser than I please explain to me why the following code segment faults? There is no problem allocating the memory by reference, but as soon as I try to assign anything or free by reference, segfault occurs. I'm sure I'm missing some fundamental concept about pointers and passing by reference, hopefully some light can be shed. ``` #include <stdlib.h> #include <stdio.h> void allocateMatrix(float ***); void fillMatrix(float ***); void freeMatrix(float **); int main() { float **matrix; allocateMatrix(&matrix); // this function calls and returns OK fillMatrix(&matrix); // this function will segfault freeMatrix(matrix); // this function will segfault exit(0); } void allocateMatrix(float ***m) { int i; m = malloc(2*sizeof(float*)); for (i = 0; i < 2; i++) { m[i] = malloc(2*sizeof(float)); } return; } void fillMatrix(float ***m) { int i,j; for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { (*m)[i][j] = 1.0; // SEGFAULT } } return; } void freeMatrix(float **m) { int i; for (i = 0; i < 2; i++) { free(m[i]); // SEGFAULT } free(m); return; } ```

Original source