Reputation: 13
I have a structure that uses double pointers to make a matrix:
typedef struct
{
int rows, cols;
int** element;
}Matrix;
I am writing a function that initializes a matrix by dynamically allocating memory to this structures. This is the code I have written but I get a segmentation fault when I try to access a->rows,cols, or element in another function or in main.
void matrixInit (Matrix* ma, int m, int n)
{ int i;
ma=(Matrix*)malloc(sizeof(Matrix));
ma->rows=m;
ma->cols=n;
ma->element=malloc(m*sizeof(int*));
for(i=0;i<m;i++)
{ma->element[i]=malloc(n*sizeof(int));
}
}
Any help please?
Upvotes: 1
Views: 2126
Reputation: 699
When you call a function like this, you pass it a value of a pointer to a matrix. When you actually create the matrix in the function, you only assign it locally.
You should pass a pointer to the variable where the matrix pointer is to be stored, i.e. Matrix **ma
.
void matrixInit (Matrix **ma_ptr, int m, int n)
{
int i;
*ma_ptr = (Matrix*)malloc(sizeof(Matrix));
Matrix *ma = *ma_ptr;
ma->rows=m;
ma->cols=n;
ma->element=malloc(m*sizeof(int*));
for(i=0;i<m;i++)
{
ma->element[i]=malloc(n*sizeof(int));
}
}
and then call this method with an address ofthe variable where you want your matrix to be stored.
Matrix *m;
matrixInit(&m, 4, 4);
Another way is to allocate memory for the matrix itself outside of the function. Your function will stay exactly the way you wrote it, except you remove the allocation
ma = (Matrix*)malloc(sizeof(Matrix));
Then you will pass it a pointer to a Matrix, but you have to ensure it points to a Matrix struct. You can do this by declaring a Matrix*
variable and calling malloc() outside of the function (and thus allocating it on the heap), or declare a variable of type Matrix
(and have it allocated on the stack).
Matrix ma;
matrixInit(&ma, 4, 4);
Upvotes: 0
Reputation: 68033
Your function doesn't return the matrix it creates. Do this instead.
Matrix * matrixInit (int m, int n)
{
Matrix* ma;
int i;
ma=(Matrix*)malloc(sizeof(Matrix));
...
return ma;
}
... and then use it thus
Matrix * myMatrix;
myMatrix = matrixInit(8,8); // chessboard
Upvotes: 0
Reputation: 3302
In C, every function argument is passed by value. This means that when you give an argument to a function, a copy of the value (not the value itself) is passed as the argument in the function. This includes pointers - you can change whatever the pointer refers to and have no problems, but if you set the pointer to point to something else in the function, the change only applies to a local copy of the pointer.
ma=(Matrix*)malloc(sizeof(Matrix));
Here, instead of making the input pointer point to a newly allocated memory for a Matrix
struct, you are in fact overwriting a local pointer ma
with a new one without doing anything to the input pointer. This causes the issue. To fix this, you could return a pointer to ma
instead.
Upvotes: 1
Reputation: 8053
You'll want to pass in a pointer-to-pointer-to-Matrix so that the malloced pointer is available to the caller. Like this:
void matrixInit (Matrix ** ma, int m, int n)
{
*ma = malloc(sizeof **ma); // sizeof **ma == sizeof(Matrix)
Then call it with this:
Matrix * matx;
matrixInit(&matx, 3, 4);
Upvotes: 0