Search code examples
carrayssegmentation-faultpass-by-pointer

Why did my array get transposed?


I want declare a 2D array of doubles (double** data). I want to pass this by address to a helper function; so I pass &data and the helper function has argument double*** d.

Passed this way, the indexing that I used for the 2D array in the main function is no longer working.

Test code:

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

void helperfunction(double*** data, int n, int c) {

    printf("\nIn helper function\n");

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < c; j++) {
            printf("(%i %i %lf) ", i, j, *data[i][j]);
        }
        printf("\n");
    }

}

int main(int argc, char **argv) {

    int n = 4; //number of rows
    int c = 4; //number of columns

    double count = 0.0;

    double** data = malloc(n * sizeof(double*));

    for (int i = 0; i < n; i++) {
        double* row = malloc(c * sizeof(double));
        for (int j = 0; j < c; j++) {
            row[j] = count;
            count += 1.2;
        }
        data[i] = row;
    }

    printf("In main function\n");

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < c; j++) {
            printf("(%i %i %lf) ", i, j, data[i][j]);
        }
        printf("\n");
    }

    helperfunction(&data, n, c);

    return 0;
}

Output:

In main function
(0 0 0.000000) (0 1 1.200000) (0 2 2.400000) (0 3 3.600000) 
(1 0 4.800000) (1 1 6.000000) (1 2 7.200000) (1 3 8.400000) 
(2 0 9.600000) (2 1 10.800000) (2 2 12.000000) (2 3 13.200000) 
(3 0 14.400000) (3 1 15.600000) (3 2 16.800000) (3 3 18.000000) 

In helper function
(0 0 0.000000) (0 1 4.800000) (0 2 9.600000) (0 3 14.400000) 
Segmentation fault (core dumped)

Obviously, something is wrong with the indexing when I deference the address (*data[i][j]) in the helper function. What is causing this?


Solution

  • *data[i][j] does not do what you think. It is equivalent to *(data[i][j]). Your options are:

    1. Use (*data)[i][j] instead, or

    2. Pass data (instead of &data) and use data[i][j] since passing a triple pointer isn't necessary here.