在结构中初始化并访问一个指针,该指针动态指向一个指针数组

问题描述 投票:1回答:1

我的任务是实现一个函数,该函数接收行和列的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;
}

[我运行程序时,即使我尝试在仅包含[0-1] [0-1]个元素的矩阵中访问索引[1] [5],也没有收到任何警告或编译器错误,返回0.0,这应该不会发生。出了什么问题?

而且我应该在什么时候释放程序中分配的内存,我该怎么做?

提前感谢!

编辑:

我现在知道我的测试结果是未定义行为的结果,而不是由于我方面的错误。

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

c pointers matrix struct dynamic-memory-allocation
1个回答
0
投票

您的测试结果是未定义的行为,因为您访问未初始化的内存空间。编译器无法给您警告或错误,因为您不知道数组的维数,因为您将其声明为指针。

要释放内存,您可以这样做:

for(i_rows = 0; i_rows < n_rows; i_rows++){
      free(positions[i_rows]);
}
free(positions);

这样,您将重新分配矩阵的所有行以及行的容器。 (显然,“ position”是指向矩阵的指针)。

必须在对矩阵进行所有操作之后再释放内存。在示例情况下,您可以将其放在printf之后的主体中。

我建议您创建一个新函数来删除矩阵,在该矩阵中将指针传递给矩阵和行数。例如:

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

然后在需要时调用它。

© www.soinside.com 2019 - 2024. All rights reserved.