在C中读取先前未知大小的矩阵

时间:2018-03-31 15:15:05

标签: c pointers matrix

此函数的输入应该是一对整数 - 矩阵的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分配给分配读取矩阵的地址时的新值。我怎么能在这里使用指针?

3 个答案:

答案 0 :(得分:1)

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

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 :(得分: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);
}

答案 2 :(得分:1)

您的代码中有2个错误:

  • 您应该将matrix中的main定义为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;
}