C 初始化和访问结构中动态指向指针数组的指针
我的任务是实现一个函数,该函数作为参数接收行和列的int值 然后,我必须使用收到的行和列动态生成一个矩阵 接下来我必须用0填充矩阵的每个坐标 最后但并非最不重要的一点是,我必须返回一个指向刚刚初始化的矩阵的指针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
#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代码>-为什么数据
得到了所有的爱?行和列不应该