Search code examples
cmemory-managementmallocdynamic-memory-allocation

Dynamic memory allocation question (in C)


Consider following codes:

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

void allocateMatrix(int **m, int l, int c)
{
    int i;

    m = (int**) malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        m[i] = (int*) malloc( sizeof(int) * c );
}

int main()
{
    int **m;
    int l = 10, c = 10;
    allocateMatrix(m, l, c);
    m[0][0] = 9;
    printf("%d", m[0][0]);

    return 0;
}

The code above will generate an memory allocation error and will crash.

But the code below will work correctly, the question is: WHY?

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

int** allocateMatrix(int l, int c)
{
    int i;

    int **m = (int**) malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        m[i] = (int*) malloc( sizeof(int) * c );
    return m;
}

int main()
{
    int **m;
    int l = 10, c = 10;
    m = allocateMatrix(l, c);
    m[0][0] = 9;
    printf("%d", m[0][0]);

    return 0;
}

I cannot see why the first code crashes, since I'm just passing the pointer-to-pointer m (the variable that holds the memory first memory address of the matrix) as an argument. I see no difference between the codes (in practice). I would appreciate any clear explanation.

Thank you, Rafael Andreatta


Solution

  • In the first example you don't initialize m. You merely change your copy of it. So, put otherwise, the caller will never see what you did to m.

    In the second example you allocate memory and then return a pointer to it. Which is valid.

    You might be able to fix your first example like this (untested but should work):

    void allocateMatrix(int ***m, int l, int c)
    {
        int i;
    
        *m = malloc( sizeof(int*) * l );
        for(i = 0; i < l; i++)
            (*m)[i] = malloc( sizeof(int) * c );
    }
    
    
    /* ... */
    
    allocateMatrix(&m, l, c);
    

    EDIT

    Took me a while but I found it. As usual the C FAQ has something to say about this.