C - allocating a matrix in a function
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
Solution 1:
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])
Solution 2:
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.
Solution 3:
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;
}