Search code examples
cpointersmatrix

Is it correct this declaration of a matrix as a double pointer in C?


I am new in C programming language and I don't know whether my code is correct and efficient enough or there is something I am misunderstanding. The only thing I want to do is to allocate dynamic memory in my main function for a matrix of n rows and m columns. Then, I want to initialize it by passing it by reference to function matrix_access. Finally, I just print the values to verify the matrix has been initialized correctly.

I have done it by means of declaring **matrix, but I have seen in some other websites declarations as a triple pointer and I don't get it. In my code, I am interpreting my memory allocation as allocating first memory to the first element in each row and then, allocating memory for each element in the row. Is it correct or my understanding is completely wrong?

Many thanks in advance.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>


void matrix_access(double ** matrix, int n, int m);

int main()
{
    int n = 5, m = 4;
    double **matrix = malloc(n * sizeof(double*));  // pointer to the first element of each row
    for (int i = 0; i < n; i++)
    {
        matrix[i] = malloc(m * sizeof(double)); // pointer to each element in the row
    }
    
    matrix_access(matrix,n,m);
    
    printf("The values are\n");
        for (int i = 0; i < n; i++) 
        {
            for (int j = 0; j < m; j++) 
            {
                    printf("%lf ", matrix[i][j]);
            }
            printf("\n");
        }
    return 0;
}


void matrix_access(double ** matrix, int n, int m)
{
    int arr1[5][5] = { { 0, 1, 2, 3},
                       { 2, 3, 4, 5},
                       { 4, 27, 6, 7},
                       { 5, 4, 3, 2},
                       { 2, 5, 4, 3} };
        for (int i = 0; i < n; i++) 
        {
        for (int j = 0; j < m; j++) 
        {
            matrix[i][j] = arr1[i][j];
            }
        }
}

Solution

  • I have done it by means of declaring **matrix,

    I do not like this approach to representing matrices, but it is nonetheless relatively common.

    but I have seen in some other websites declarations as a triple pointer and I don't get it.

    One might use a triple pointer as a function argument if one wants the function to modify a double pointer (itself) whose address the caller passes. The code you've presented does not rely on that mechanism for exchanging data.

    In my code, I am interpreting my memory allocation as allocating first memory to the first element in each row and then, allocating memory for each element in the row.

    Your code looks ok, but that description is off. The structure you are creating is an array of pointers, each one pointing to the data for a different row. Thus, your first allocation is for the array of pointers. None of these are, themselves, elements of the matrix you are modeling. The later allocations are each for all the elements of a single row.

    Is it correct or my understanding is completely wrong?

    Your code looks fine to me. Your understanding is a little off.


    For what it's worth, when I can rely on fixed array dimensions or on variably-modified types, I prefer to use a contiguously allocated representation for matrices. Something like this:

    void matrix_access(int n, int m, double (*matrix)[m]) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                matrix[i][j] = (double) rand() / RAND_MAX;
            }
        }
    }
    
    int main(void) {
        int n = 5, m = 4;
        double (*matrix)[m] = malloc(n * sizeof(*matrix));  // all elements
        
        matrix_access(n, m, matrix);
        
        printf("The values are\n");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                printf("%lf ", matrix[i][j]);
            }
            printf("\n");
        }
    
        free(matrix); // only one free needed for the whole matrix
    
        return 0;
    }