动态二维数组,无内存

Dynamic 2D array and memory free

我在弄清楚如何正确地创建二维动态数组、如何断言内存以及最后如何释放它时遇到了很大的麻烦。

我会向您展示我的部分代码,请告诉我哪里做错了。

我在 main 函数中声明动态数组并将其发送到 BuildMatrix 函数,该函数应该断言数组所需的内存并填充它。

这就是我在数组上声明并将其发送到函数 Build:

的方式
int row, column, i, j;
int **matrix; 
BuildMatrix(&matrix, row, column);

现在这就是 BuildMatrix decleration:

void BuildMatrix(int*** matrix, int row, int column);

这就是我断言内存的方式(行和列具有用户选择的值)

matrix =malloc(row * sizeof(int *));
for (i = 0; i < row; i++)
matrix[i] =malloc(column * sizeof(int));

到目前为止一切正常,但是当我尝试释放内存时,出现断点错误

这是我用来释放内存的函数:

void ExitAndFree(int** matrix, int row) {
    int i;
    for (i = 0; i < row; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

调试器告诉我错误在第一个 free 上(如果我删除第一个,第二个就会给出错误)

还有一个问题,不过我觉得暂时就这么多,待会再问...:P

感谢您的帮助!!

P.S:如果您有任何关于指针和动态数组(我宁愿 2D+ 数组)的好教程,我将不胜感激。

这里有一个复制粘贴的例子...

#include <stdlib.h>

void BuildMatrix(int*** matrix, int row, int column) {
    *matrix = malloc(row * sizeof(int *));
    int i;
    for (i = 0; i < row; i++)
        (*matrix)[i] = malloc(column * sizeof(int));
}

void ExitAndFree(int** matrix, int row) {
    int i;
    for (i = 0; i < row; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

int main()
{
    int row = 10, column = 10;
    int **matrix;
    BuildMatrix(&matrix, row, column);
    ExitAndFree(matrix, row);

    return 0;
}

但是我强烈建议不要直接使用原始指针和单独的矩阵变量。明智的软件工程解决方案是使用现有的矩阵库,或者使用 C 语言编写您自己的矩阵库 struct...

我认为您在这里不需要 *** 指针,相反 BuildMatrix 可以 return **main()。这种设计更改将使您的程序更容易,因为使用 *** 有时会很痛苦。

您也没有检查 malloc()scanf() 的 return 值,这可能会导致将来出现问题,先检查这些值会更安全。我还建议你 Don't cast result of malloc(),因为这在 C 中并不是真正需要的。

由于您在@flintlock 的回答中发布的代码存在 free() 错误,您的代码存在不一致:

您已声明:

void ExitAndFree(int** matrix, int row)

什么时候应该改为:

void ExitAndFree(int*** matrix, int row)

您的代码需要进行此更改,因为您在 main 中为 ExitAndFree() 调用 &matrix,因此在此函数中使用 **matrix 还不够好。同样,这是因为代码使用了 ***,这让生活变得更加艰难。

您的代码似乎适用于此更改 here

根据这些建议,您还可以像这样实施您的程序:

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

int **BuildMatrix(int row, int column);
void PrintAndFree(int **matrix, int row, int column);

int main(void) {
    int **matrix, row, column;

    printf("\nPlease enter number of rows:\n");
    if (scanf("%d", &row) != 1) {
        printf("Invalid rows.\n");
        exit(EXIT_FAILURE);
    } 

    printf("\nPlease enter number of columns:\n");
    if (scanf("%d", &column) != 1) {
        printf("Invalid columns.\n");
        exit(EXIT_FAILURE);
    }

    matrix = BuildMatrix(row, column);

    PrintAndFree(matrix, row, column);

    return 0;
}

int **BuildMatrix(int row, int column) {
    int **matrix, rows, cols;

    matrix = malloc(row * sizeof(*matrix));
    if (matrix == NULL) {
        printf("Cannot allocate %d rows for matrix.\n", row);
        exit(EXIT_FAILURE);
    }

    for (rows = 0; rows < row; rows++) {
        matrix[rows] = malloc(column * sizeof(*(matrix[rows])));
        if (matrix[rows] == NULL) {
            printf("Cannot allocate %d columns for row.\n", column);
            exit(EXIT_FAILURE);
        }
    }

    printf("\nPlease enter values to the matrix:\n");
    for (rows = 0; rows < row; rows++) {
        for (cols = 0; cols < column; cols++) {
            if (scanf("%d", &matrix[rows][cols]) != 1) {
                printf("Invalid value entered.\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    return matrix;
}

void PrintAndFree(int **matrix, int row, int column) {
    int rows, cols;

    printf("\nYour matrix:\n");
    for (rows = 0; rows < row; rows++) {
        for (cols = 0; cols < column; cols++) {
             printf("%d ", matrix[rows][cols]);
        }
        free(matrix[rows]);
        matrix[rows] = NULL;
        printf("\n");
    }

    free(matrix);
    matrix = NULL;
}