在C语言中读取未知大小的矩阵

4
这个函数的输入应该是一对整数,即矩阵的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分配给读取矩阵分配的地址的新值时,它会崩溃。我应该如何处理这些指针?


1
这个答案非常相关于你的问题:This answer - Basile Starynkevitch
3个回答

1
直接问题是您正在尝试从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;
}

注意,您可以直接传递指针表达式&row&col,而不必为它们创建指针变量。对于matrix也是如此,它在您的实现中是一个整数的平面数组,并覆盖了您自己的2D寻址方案。

1

你不能这样做。问题在于如果你在编译时没有固定双重数组的大小,就不能分配它并使用它。为了能够这样做并继续使用具有子索引符号的矩阵,你需要使用指向整数数组的指针数组:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接