Search code examples
cmemory-managementcalloc

Understand Allocation of matrix c


I have the following function:

float **alloc_float_matrix(int n) {
    int i;
    float **m = (float**)calloc(n, sizeof(float*));
    for (i = 0; i < n; i++) {
        m[i] = (float*)calloc(n, sizeof(float));
    }
    return m;
}

I want to find out why is this works

float **m = (float**)calloc(n, sizeof(float*));

And how will be memory allocated. What i want to see is the layout of addresses. In this moment i think is: m is pointing to an array of arrays. And after that are the next n element for each array

m[1] m[2] m[3] m[4] m[5]... m[n] (row1)n[1] n[2] n[3] n[4] n[5] n[6] n[7] ...n[n] (row2)n[1] n[2] n[3] n[4] n[5] n[6] n[7] ...n[n]...

Is this representation correct?


Solution

  • What have you done here:

    float **m = (float**)calloc(n, sizeof(float*));
    
    1. You have created a pointer of type float**.
    2. Then you assign this pointer the initial address of a sequential block of memory consisting of

      (n * sizeof(float*))

    bytes. All these bytes have got the value of zero in them. You can address n elements now from this memory block, each holding

    sizeof(float*)
    

    bytes, i.e:

    m[0], m[1], m[2], ... , m[n - 1]

    where m[0] will return you the actual value of the first element from the memory block, which is a memory address.

    1. The next thing you do is: you take each of these elements (m[0], m[1], etc.) and assign to each of them new different memory blocks at different memory locations. Each of these memory blocks consist of

      (n * sizeof(float*))

    bytes and you can address n elements, where each element consists of

    sizeof(float)
    

    bytes, i.e:

    (row 0) m[0][0], m[0][1], m[0][2], . . ., m[0][n - 1]

    (row 1) m[1][0], m[1][1], m[1][2], . . ., m[1][n - 1]

    . . .

    (row n - 1) m[n - 1][0], m[n - 1][1], m[n - 1][2], . . ., m[n - 1][n - 1]

    So overall, what you get is: An array, m, that holds n consecutive memory addresses where each of those memory addresses point to n memory blocks all located at different addresses. Each of them hold

    (n * sizeof(float))
    

    bytes, all consecutive. You cannot say that the next memory location after m[0][n - 1] is m[1][0], but you can say that the next memory location after m[0][n - 2] is m[0][n - 1]