将存储分配给矩阵

时间:2011-04-25 03:50:51

标签: c

我正在编写一个将存储分配给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;

为什么会这样?

3 个答案:

答案 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);
}