我正在编写一个将存储分配给nxn矩阵的函数。
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);
}
}
return;
}
但是如果我运行以下代码,我会在最后一个语句中得到一个段错误:
double **A;
assign_matrix_storage(A, 2);
A[1][1] = 42;
为什么会这样?
答案 0 :(得分:3)
这种情况正在发生,因为A
没有改变assign_matrix_storage()
。 C是按值传递的,因此您传入A的副本。因此,您在函数中对A所做的更改将丢失。该参数必须类似于double ***pointerToA
,然后当您调用该函数时,assign_matrix_storage(&A, 2);
显然在assign_matrix_storage()
内,您需要正确地尊重pointerToA
一个“电平”。
答案 1 :(得分:3)
您已经为矩阵分配了内存(完美),但实际上并没有将其分配给来自被调用者的A
变量。相反,A
最终仍未初始化,并尝试分配给A[1][1]
导致段错误。为了能够做到这一点,你需要一个指向该变量的指针并将矩阵分配给该地址。因此,实际上,您的函数签名和实现需要更改:
/* 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;
更好的替代方法是将指针返回到新矩阵,并将其指定给变量。
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;
答案 2 :(得分:1)
也许这种实现很有用。
/* 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);
}