【问题标题】:allocating storage to a matrix将存储分配给矩阵
【发布时间】:2011-08-12 02:41:48
【问题描述】:

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

这是为什么?

【问题讨论】:

标签: c


【解决方案1】:

您已经(完美地)为您的矩阵分配了内存,但实际上并未将其分配给被调用方的 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】:

    也许这个实现很有用。

    /* 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);
    }
    

    【讨论】:

      【解决方案3】:

      这是因为A 没有被assign_matrix_storage() 更改。 C 是按值传递的,因此您传递的是 A 的 副本。因此,您在函数中对 A 所做的更改将丢失。参数必须是 double ***pointerToA 之类的东西,然后当您调用该函数时,您会执行 assign_matrix_storage(&amp;A, 2); 显然在 assign_matrix_storage() 内部,您需要正确地将 pointerToA 遵循一个“级别”。

      【讨论】:

      • 返回double** 可能比接受double*** 作为参数更好。
      • 好点!让assign_matrix_storage() 获取int n 并让它进行分配并返回double **。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多