I'm writing a function that allocates storage to an nxn matrix.
void assign_matrix_storage(double **matrix, int n){
if((matrix = malloc(n * sizeof(double*))) == NULL){
printf("ERROR: Memory allocation failed\n");
exit(EXIT_FAILURE);
}
int i;
for(i = 0; i < n; i++){
if((matrix[i] = malloc(n * sizeof(double))) == NULL){
printf("ERROR: Memory allocation failed\n");
exit(EXIT_FAILURE);
}
}
ret开发者_如何学Pythonurn;
}
However if I run the following code, I get a segfault on the last statement:
double **A;
assign_matrix_storage(A, 2);
A[1][1] = 42;
Why is this?
You've allocated the memory for your matrix (perfectly) but you don't actually assign it to the A
variable from the callee. Instead, A
ends up still uninitialized and attempting to assign to A[1][1]
caused a segfault. To be able to do that, you'd need a pointer to that variable and assign your matrix to that address. So in effect, your function signature and implementation would need to change:
/* take a pointer to a (double **) */
void assign_matrix_storage(double ***matrix, int n){
/* then all accesses need to dereference first */
if(((*matrix) = malloc(n * sizeof(double*))) == NULL){
printf("ERROR: Memory allocation failed\n");
exit(EXIT_FAILURE);
}
int i;
for(i = 0; i < n; i++){
if(((*matrix)[i] = malloc(n * sizeof(double))) == NULL){
printf("ERROR: Memory allocation failed\n");
exit(EXIT_FAILURE);
}
}
return;
}
/* then call */
double **A;
assign_matrix_storage(&A, 2);
A[1][1] = 42;
A better alternative to what you have would be to return the pointer to the new matrix instead and assign that to your variable.
double **assign_matrix_storage(int n) {
double **matrix;
/* the rest of your implementation */
return matrix;
}
double **A;
A = assign_matrix_storage(2);
A[1][1] = 42;
It's happening because A
isn't getting changed by assign_matrix_storage()
. C is pass-by-value, so you're passing in a copy of A. So the change you make to A in the function is lost. The parameter needs to be something like double ***pointerToA
and then when you call the function you'd do assign_matrix_storage(&A, 2);
And obviously inside assign_matrix_storage()
you'll need to properly deference pointerToA
one "level".
Maybe this implementation is useful.
/* Allocate space for a unit-off-set (m times n) matrix b[1..n][1..m] */
/* Note that b_{ij}=b[j][i], so the i'th column is b[i] */
double **matrix(int m, int n){
int i;
double **a = (double **)malloc(n*sizeof(double *));
double **b=a-1; /* make unit off-set */
for (i=1; i<=n; i++) b[i] = (double *)malloc((m+1)*sizeof(double)); // m+1, not m!
return(b);
}
精彩评论