C 初始化和访问结构中动态指向指针数组的指针

C 初始化和访问结构中动态指向指针数组的指针,c,pointers,matrix,struct,dynamic-memory-allocation,C,Pointers,Matrix,Struct,Dynamic Memory Allocation,我的任务是实现一个函数,该函数作为参数接收行和列的int值 然后,我必须使用收到的行和列动态生成一个矩阵 接下来我必须用0填充矩阵的每个坐标 最后但并非最不重要的一点是,我必须返回一个指向刚刚初始化的矩阵的指针 #include <stdio.h> #include <stdlib.h> struct Matrix { int rows; // number of rows int cols; // number of columns doub

我的任务是实现一个函数,该函数作为参数接收行和列的int值

然后,我必须使用收到的行和列动态生成一个矩阵

接下来我必须用0填充矩阵的每个坐标

最后但并非最不重要的一点是,我必须返回一个指向刚刚初始化的矩阵的指针

#include <stdio.h>
#include <stdlib.h>


struct Matrix {
    int rows; // number of rows
    int cols; // number of columns
    double** data; // a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
};
typedef struct Matrix Matrix;

/*
* Creates a zero-initialized matrix of rows and columns matrix.
* n_rows = number of rows
* n_cols = number of columns
* return a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
*/
Matrix* new_matrix(int n_rows, int n_cols) {

    int i_rows;
    int i_cols;
    // Memory allocation of array of pointers -> array of n_row pointers
    double **positions = (double **)malloc(n_rows * sizeof(double *));
    // Row initialized as array of n_cols
    for(i_rows = 0; i_rows < n_rows; i_rows++){
      positions[i_rows] = (double *)malloc(n_cols * sizeof(double));
    }

    // elements of matrix are initialized as 0.0
    for(i_rows = 0; i_rows < n_rows; i_rows++){
      for(i_cols = 0; i_cols < n_cols; i_cols++){
        positions[i_rows][i_cols] = 0.0;
      }
    }

    Matrix *newM = malloc(sizeof(Matrix));
    newM->rows = n_rows;
    newM->cols = n_cols;
    newM->data = positions;


    return newM;
}

int main(void) {

    Matrix* test = new_matrix(2,2);
    printf("%.1f\n", test->data[1][5]); //Returns 0.0 allthough that should not happen


    return 0;
}
#包括
#包括
结构矩阵{
int rows;//行数
int cols;//列数
double**data;//指向n_行数组的指针指向行;行是n_cols double的数组
};
类型定义结构矩阵;
/*
*创建由行和列矩阵组成的零初始化矩阵。
*n_行=行数
*n_cols=列数
*返回指向n_行数组的指针指向行的指针;行是n_cols double的数组
*/
矩阵*新矩阵(整数行,整数列){
int i_行;
国际货币基金组织;
//指针数组的内存分配->n_行指针数组
双**位置=(双**)malloc(n_行*sizeof(双*);
//行初始化为n_列的数组
对于(i_行=0;i_行rows=n_行;
newM->cols=n_cols;
newM->data=位置;
返回newM;
}
内部主(空){
矩阵*测试=新的_矩阵(2,2);
printf(“%.1f\n”,test->data[1][5]);//返回0.0,尽管这不应该发生
返回0;
}
当我运行程序时,我没有收到任何警告或编译器错误,即使我尝试访问矩阵中的索引[1][5],该矩阵应该只有[0-1][0-1]元素,但我得到了0.0,这是不应该发生的。出了什么问题

另外,我应该在什么时候释放()程序中分配的内存,以及如何释放

提前谢谢

编辑:

我现在意识到,我的测试结果是未定义行为的结果,而不是我的错误


但是,我仍然不确定如何释放动态分配矩阵的内存,以及在我的程序中必须在什么时候执行此操作?

您的测试结果是未定义的行为,因为您访问了未命名的内存空间。 编译器无法向您发出警告或错误,因为您不知道数组的维度,因为您将其声明为指针

要释放内存,可以执行以下操作:

for(i_rows = 0; i_rows < n_rows; i_rows++){
      free(positions[i_rows]);
}
free(positions);
for(i_行=0;i_行
通过这种方式,您可以取消分配矩阵的所有行以及行的容器。(显然“位置”是指向矩阵的指针)

在对矩阵进行所有操作之后,必须放置内存的空闲部分。 在本例中,您可以将其放在printf之后的main中

我建议您创建一个新函数来删除传递指向矩阵的指针和行数的矩阵。 例如:

void free_matrix(Matrix* matrix , int n_rows) {
    for(int i_rows = 0; i_rows < n_rows; i_rows++){
          free(matrix->data[i_rows]);
    }
    free(matrix->data);
}
void free_矩阵(矩阵*矩阵,int n_行){
for(int i_rows=0;i_rows数据[i_行]);
}
自由(矩阵->数据);
}

然后在需要时调用它。

您的测试结果是一个未定义的行为,因为您访问了未命名的内存空间。 编译器无法向您发出警告或错误,因为您不知道数组的维度,因为您将其声明为指针

要释放内存,可以执行以下操作:

for(i_rows = 0; i_rows < n_rows; i_rows++){
      free(positions[i_rows]);
}
free(positions);
for(i_行=0;i_行
通过这种方式,您可以取消分配矩阵的所有行以及行的容器。(显然“位置”是指向矩阵的指针)

在对矩阵进行所有操作之后,必须放置内存的空闲部分。 在本例中,您可以将其放在printf之后的main中

我建议您创建一个新函数来删除传递指向矩阵的指针和行数的矩阵。 例如:

void free_matrix(Matrix* matrix , int n_rows) {
    for(int i_rows = 0; i_rows < n_rows; i_rows++){
          free(matrix->data[i_rows]);
    }
    free(matrix->data);
}
void free_矩阵(矩阵*矩阵,int n_行){
for(int i_rows=0;i_rows数据[i_行]);
}
自由(矩阵->数据);
}

然后在需要时调用它。

不相关,
newM->data=positions-为什么
数据
得到了所有的爱?
成员是否也应该参与该操作?也就是说,与您的“问题”相关,您的代码使用
test->data[1][5]
调用未定义的行为。您评论说“返回0.0,尽管这不应该发生”。我不确定你期望的是什么,但它与你实际得到的是平等的。未定义的行为就是这样;未定义。如果你运气不好,它甚至可能看起来工作正常。@WozCraig在函数中添加了其他结构组件init。我不确定这是未定义的行为还是我的错误。如果我在主[2][0]中打印F,我会得到一个分段错误(内核转储),这是意料之中的,但是如果我对[1][100]执行相同的操作,它仍然会返回0.0。您可能不确定它是否为UB,但这就是您在这里的原因。我敢肯定,任何读过该代码的经验丰富的C工程师也是如此。编译器将准确地生成您所要求的内容,不会比所说的更少,也不会更安全。不要将定义的行为与观察到的行为混淆。可以预见,前者为后者提供了一条路径,后者本身并不保证前者。不相关,
newM->data=positions-为什么
数据
得到了所有的爱?
行和
列不应该