I am trying to allocate a matrix using a function that takes its dimensions and a triple pointer. I have allocated an int** (set to NULL) and I am passing its address as the function's argument. That gives me a mem access violation for some reason.
void allocateMatrix(int ***matrix, int row, int col) { int i; if((*matrix = (int**)malloc(row * sizeof(int*))) == NULL) { perror("There has been an error"); exit(EXIT_FAILURE); } for(i = 0; i < row; ++i) { if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL) { perror("There has been an error"); exit(EXIT_FAILURE); } } } /* main.c */ int** matrix = NULL; allocateMatrix(&matrix, MATRIX_ROW, MATRIX_COL); //error
You need to change
if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL)
to
if(((*matrix)[i] = (int*)malloc(col * sizeof(int))) == NULL) // ^ ^
You need to dereference matrix
before using the array subscript.
*matrix[i]
is equivalent to *(matrix[i])
It's a problem of operator precedence. In
if ((*matrix[i] = (int*)malloc( ... ))
the default precedence is *(matrix[i])
, while you should use (*matrix)[i]
.
I would still recommend to allocate the matrix as a contiguous array instead as a array of pointers to arrays.
I have made a solution program for gcc C11/C99 with apropriate allocation funtions based on links:
http://c-faq.com/aryptr/dynmuldimary.html
http://c-faq.com/aryptr/ary2dfunc3.html
After some discussion in comments, it is clear that matrix2 is correctly allocated, it can be passed to this function fn(int row, int col, int array[col][row]) as matrix2[0] (data in one dimensional array) with a cast to (double (*)[])
//compile with gcc --std=c11 program.c #include <stdio.h> #include <stdlib.h> #define MX 9 #define MY 14 void input_matrix(int row, int column, double matrix[row][column]); void print_matrix(int row, int column, double matrix[row][column]); double **alloc_matrix2(int row, int column); double *alloc_matrix3(int row, int column); void *alloc_matrix4(int row, int column); int main() { int i=MX, j=MY; printf("Generate input values and print matrices with functions fn(int w, int k, double matrix[w][k]) (in C99 and C11)\n"); double matrix1[i][j]; input_matrix(MX,MY,matrix1); printf("matrix static\n"); print_matrix(MX,MY,matrix1); double **matrix2; //data of matrix2 is just matrix3 matrix2=alloc_matrix2(MX,MY); input_matrix(MX,MY,(double (*)[])(*matrix2)); printf("matrix two times allocated one for pointers, the second for data (double (*)[])(m[0])\n"); print_matrix(MX,MY,(double (*)[])(matrix2[0])); free(*matrix2); free(matrix2); double *matrix3=alloc_matrix3(MX,MY); input_matrix(MX,MY,(double (*)[])matrix3); printf("matrix allocated as two-dimensional array\n"); print_matrix(MX,MY,(double (*)[])matrix3); free(matrix3); j=MY; double (*matrix4)[j]; matrix4 = (double (*)[])alloc_matrix4(MX,MY); input_matrix(MX,MY,matrix4); printf("matrix allocated via pointer to array m = (double (*)[])malloc(MX * sizeof(*m))\n"); print_matrix(MX,MY,matrix4); free(matrix4); printf("\nThe End!\n"); return 0; } void input_matrix(int row, int column, double matrix[row][column]){ for(int i=0; i<row; i++){ for(int j=0; j<column; j++) matrix[i][j]=i+1; } } void print_matrix(int row, int column, double matrix[row][column]){ for(int i=0; i<row; i++){ for(int j=0; j<column; j++) printf("%.2lf ", matrix[i][j]); printf("\n"); } } double **alloc_matrix2(int row, int column){ double **matrix; matrix=malloc(row*sizeof(double*)); matrix[0] = (double *)malloc(row*column*sizeof(double)); for(int i = 1; i < row; i++) matrix[i] = matrix[0]+i*column; return matrix; } double *alloc_matrix3(int row, int column){ double *matrix; matrix=malloc(row*column*sizeof(double)); return matrix; } void *alloc_matrix4(int row, int column){ double (*matrix)[column]; matrix = (double (*)[])malloc(row*sizeof(*matrix)); return matrix; }