【问题标题】:How to properly pass dynamic 2-d array into a function in C如何正确地将动态二维数组传递给 C 中的函数
【发布时间】:2021-09-28 23:37:20
【问题描述】:

我需要在一个函数中动态分配一个二维数组,其中包含n 行和m 列,这些列也必须从input 函数中读取。

int main()
{
    int** matrix;
    int n, m;
    input(matrix, &n, &m);
    return 0;
} 

void input(int** matrix, int* n, int* m) {
    if (scanf("%d", n) == 1 && getchar() == '\n') {
        if (*n <= 0) {
            error = 1;
        }
    }
    if (error == 0) {
        if (scanf("%d", m) == 1 && getchar() == '\n') {
            if (*m <= 0) {
                error = 1;
            }
        }
    }
    if (error == 0) {
        matrix = (int**)calloc(*n, sizeof(int*));
        for (int i = 0; i < *n; i++) {
            matrix[i] = (int*)calloc(*m, sizeof(int));
        }
        for (int i = 0; i < *n && error == 0; i++) {
            for (int j = 0; j < *m && error == 0; j++) {
                if (scanf("%d", &matrix[i][j]) == 1) {
                }
                else {
                    error = 1;
                } 
            }
        }
        for (int i = 0; i < *n; i++) {
            for (int j = 0; j < *m; j++) {
                printf("%d ", matrix[i][j]);
            }
            printf("\n");
        }
    }
}

它会正确扫描和打印值,但如果我尝试在此函数之外或在另一个函数中与 matrix 交互(例如,仅打印所有值的 output(int** matrix, int *n, int *m)我会得到内存错误。 我该如何解决这个问题? (我需要保留双指针)。

【问题讨论】:

  • 直接的方法是将matrix更改为指向int**的指针以进行更新,就像nm一样。为什么需要保留双指针?另一种方法是去掉matrix这个没用的参数,让input函数返回新分配的int**
  • 是任务的要求。至少,输入函数中的形参必须和现在一样。
  • 函数忽略了matrix 参数的值,而main 无论如何都会使用未初始化的值调用它。
  • 另一种方法是将int** matrix 视为指向指针(一维数组)的指针,并使用一维数组模拟二维数组,如array[rowIndex * width + colIndex]
  • 您的确切要求是什么?我怀疑你误会了什么。

标签: arrays c multidimensional-array dynamic-arrays


【解决方案1】:

matrix 的值没有被input 函数使用,并且main 没有为此参数传递任何有效值。

由于input 的返回类型是void,所以所有内容都需要通过指针参数传回给调用者。 nm 的值已经通过指针传回,所以matrix 的值也需要通过指针传回,如下所示:

    int* matrix;
    int n, m;
    input(&matrix, &n, &m);

请注意,调用者的matrix 变量的类型需要从int** 更改为int*。这意味着矩阵必须由int 的线性(一维)数组表示。因此,input 需要将矩阵的内存分配为一个包含int 数组的单个块,并且它需要将二维矩阵元素索引映射到一维数组索引。

input 中的分配需要是这样的:

        *matrix = calloc(*n * *m, sizeof(int));

并且ij 列的矩阵元素需要转换为一维索引,如下所示:(*matrix)[i * *m + j](其中*m 是列数)。

在同一矩阵上调用的其他函数需要执行从二维索引到一维索引的相同转换。例如:

void output(const int *matrix, int n, int m) {
   for (int i = 0; i < n; i++) {
       for (int j = 0; j < m; j++) {
           printf("%d ", matrix[i * m + j]);
       }
       printf("\n");
   }
}

示例用法:

    int* matrix;
    int n, m;
    input(&matrix, &n, &m);
    output(matrix, n, m);

【讨论】:

    猜你喜欢
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2011-05-24
    • 1970-01-01
    相关资源
    最近更新 更多