【问题标题】:Read matrix of previously uknown size in C在C中读取以前未知大小的矩阵
【发布时间】:2018-09-10 08:53:13
【问题描述】:

这个函数的输入应该是一对整数——矩阵的size——后跟col*row整数。它看起来像这样

2 3
76 98 -31
30 30 32

这是我到目前为止编写的代码。它适用于行和列大小,但是当我尝试将指针传递给读取矩阵时,它会崩溃。我对应该如何将 int** matrix 参数传递给函数感到困惑。 (我在讲座上看到过类似功能的示例,所以我更喜欢使用双指针的解决方案。

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

int load_matrix(int *ro,int *co, int **matrix);

int main(int argc, char* argv[]) {
    int row = 3;
    int col = 3;
    int *ro = &row;
    int *co = &col;
    //int matx[1];
    int **matrix; //= matx[0];
    load_matrix(ro,co,matrix);
}

int load_matrix(int* ro,int* co, int** matrix) {
    int rows, cols;
    if(scanf("%d %d",&rows,&cols)==2) {
        int *mat = malloc(sizeof(int)*rows*cols);
        int read=0;
        for(int i = 0; i<rows &&read>=0; i++) {
            for(int j = 0; j<cols && read >=0; j++) {
                if(scanf("%d", &(mat[i*cols+j]))!=1) {
                    read = -1;
                } else {
                    read++;
                }
            }
        }
        if(read == (rows*cols)) {
            *ro = rows;
            *co = cols;
            **matrix = mat; --- this crashes the program
        } else {
            free(mat);
            *matrix = 0;
        }
    } else {
        return 100;
    }
    return 0;
}

正如代码中所标记的,它崩溃的部分是当我尝试为指针int** matrix 分配一个新值到分配读取矩阵的地址时。我应该如何使用这里的指针?

【问题讨论】:

标签: c pointers matrix


【解决方案1】:

你的代码有两个错误:

  • 您应该将main 中的matrix 定义为int *matrix;,而不是双指针,但您应该将matrix 的地址传递给load_matrix 函数。

  • load_matrix 中,您应该将mat 指针简单地存储为*matrix = mat; 而不是**matrix = mat;

这是一个更正和简化的版本:

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

int load_matrix(int *ro, int *co, int **matrix) {
    int rows, cols;
    if (scanf("%d %d", &rows, &cols) == 2) {
        int *mat = malloc(sizeof(int) * rows * cols);
        int read = 0;
        for (int i = 0; i < rows && read >= 0; i++) {
            for (int j = 0; j < cols && read >= 0; j++) {
                if (scanf("%d", &mat[i * cols + j]) != 1) {
                    read = -1;
                } else {
                    read++;
                }
            }
        }
        if (read == rows * cols) {
            *ro = rows;
            *co = cols;
            *matrix = mat;
        } else {
            free(mat);
            *matrix = NULL;
        }
        return 0;
    } else {
        return 100;
    }
}

int main(int argc, char *argv[]) {
    int row, col, *matrix;
    load_matrix(&row, &col, &matrix);
    return 0;
}

【讨论】:

    【解决方案2】:

    直接的问题是您试图从main 取消引用未初始化的指针matrix。从你的程序流程来看,你应该这样调用你的函数:

    int main(int argc, char* argv[]){
        int row;
        int col;
        int *matrix;
        if (load_matrix(&row, &col, &matrix) != 0) {
            // Report an error
            return -1;
        }
        printf("Got a matrix %d by %d\n", row, col);
        // ... 
        // At the end you should free the matrix
        free(matrix);
        return 0;
    }
    

    请注意,您可以直接为&amp;row&amp;col 传递指针表达式,而无需为它们创建指针变量。 matrix 也是如此,在您的实现中,它是一个平面整数数组,上面覆盖有您自己的二维寻址方案。

    【讨论】:

      【解决方案3】:

      你不能那样做。问题是,如果您在编译时没有固定两个维度的大小,则无法分配并使用二维数组。为了能够做到这一点并继续使用带有子索引符号的矩阵,您需要使用指向整数数组的指针数组:

      #include <stdlib.h>
      #include <stdio.h>
      int **load_matrix(int *colsref, int *rowsref)
      {
          int cols, rows, r, c;
      
          scanf("%d%d", &rows, &cols);
          int **res = malloc(sizeof (int *) * rows); // array of pointers to rows.
          if (!res) return NULL; // no memory.
          for(r = 0; r < rows; r++) {
              res[r] = malloc(sizeof (int) * cols); // each row.
              if (!res[r]) {
                  int i, j; // free all allocated memory
                  for (i = 0; i < r; i++) free(res[i]);
                  free(res);
                  return NULL;
              }
              for (c = 0; c < cols; c++)
                  scanf("%d", &res[r][c]);
          }
          *colsref = cols; *rowsref = rows;
          return res;
      }
      

      现在您可以将矩阵单元称为mat[row][col]。您需要一个类似的模型来释放矩阵。我已经稍微改变了界面以使代码更具可读性:(完整示例)

      #include <stdlib.h>
      #include <stdio.h>
      
      int **load_matrix(int *rowsref, int *colsref)
      {
          int cols, rows, r, c;
      
          scanf("%d%d", &rows, &cols);
          int **res = malloc(sizeof (int **) * rows); // array of pointers to arrays.
          if (!res) return NULL;
          for(r = 0; r < rows; r++) {
                  res[r] = malloc(sizeof (int *) * cols);
                  if (!res[r]) {
                          int i, j; // free all allocated memory
                          for (i = 0; i < r; i++) free(res[i]);
                          free(res);
                          return NULL;
                  }
                  for (c = 0; c < cols; c++)
                          scanf("%d", &res[r][c]);
          }
          *colsref = cols; *rowsref = rows;
          return res;
      }
      
      void print_matrix(int **matrix, int rows, int cols)
      {
          int r, c;
          printf("%d %d\n", rows, cols);
          for (r = 0; r < rows; r++) {
                  for (c = 0; c < cols; c++)
                          printf("\t%d", matrix[r][c]);
                  printf("\n");
          }
      }
      
      void free_matrix(int **matrix, int rows)
      {
          int r;
          for (r = 0; r < rows; r++)
                  free(matrix[r]);
          free(matrix);
      }
      
      int main()
      {
          int **matrix, rows, cols;
      
          matrix = load_matrix(&rows, &cols);
          print_matrix(matrix, rows, cols);
          free_matrix(matrix, rows);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-09
        • 1970-01-01
        • 2015-04-27
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 2016-12-13
        • 2016-01-02
        相关资源
        最近更新 更多