首页 > 解决方案 > 带有malloc的二维数组,函数调用分配

问题描述

我正在做一个项目,但我遇到了一个问题。我正在尝试读取一个文件,该文件在第一行中包含一个给出行数的数字,然后跟随整数矩阵,用空格分隔。

我想在main中做一个指针,然后用指针作为参数调用函数,函数应该读取txt文件中的第一个数字,然后用malloc创建一个二维数组,然后读取文本文件中的矩阵并返回。但是要么我得到它,所以函数可以分配和读取矩阵,但是在调用函数时我的指针有问题,所以我不能使用分配和读取的东西,或者我在尝试调用时出错然后在函数中引用和分配东西。

void readjobs(FILE* fp, int ***array, int linesToRead, int facilityCount) {
    int ch = 0;
    int rows = 0;
    while ((ch = fgetc(fp)) != '\n')
    {
        rows = ch - 48;
        //rows = rows * 10 + (ch - 48);
    }

    if (rows > linesToRead) rows = linesToRead;

    *array = (int**)malloc(rows * sizeof(int*));
    for (int i = 0; i < rows; i++) {
        /* size_y is the height */
        *array[i] = (int*)malloc(facilityCount * sizeof(int));
    }
    int i = 0, j = 0;
    while ((ch = fgetc(fp)) != EOF)
    {
        if (ch == '\n')
        {
            i++;
            printf("\n");
        }
        else if (ch == ' ')
        {
            j++;
            printf("%i ", *array[i][j]);
        }
        else    //wenn es ne nummer ist
        {
            *array[i][j] = (*array[i][j] * 10) + (ch - 48);
        }
    }
}

int main(int argc, char** argv) {

    int facilities_count = -1;
    int jobs_count = -1;
    int **jobs = NULL;
    FILE *fp;   //Zeiger für Datei
    fp = fopen("jobs.txt", "r");    //Dateizugriff, Datei als read 

    if (fp == NULL) {   //falls die Datei nicht geoeffnet werden kann
        printf("Datei konnte nicht geoeffnet werden!!\n");
    }
    else {  //Datei konnte geoeffnet werden
        printf("Datei ist lesbar\n");

        readjobs(fp, &jobs, 6, 6);

        if (jobs == NULL)printf("nullpionter");
        else {
            for (int i = 0; i < 6; i++) {
                printf("\n");
                for (int j = 0; j < 6; j++) {
                    printf("%x ", jobs[i][j]);
                }
            }
        }
        fclose(fp); //Dateizugriff wieder freigeben
    }

    MPI_Finalize();
    getchar();
    return 0;
}

文本文件示例:

6
3 2 2 1 5 4
1 1 3 4 2 0
1 2 3 4 5 1
3 4 2 0 1 5
1 0 5 2 3 4
4 0 1 3 5 2

在这种情况下,第一个数字“6”是多少行,其余的是要读取的矩阵

标签: cpointersmultidimensional-arraymallocfunction-call

解决方案


你的主要问题

我通过调试编译了您的代码:

$ cc -g mat.c -Wall -Wextra

在调试器中运行它:

$ gdb a.out
(gdb) run
Starting program: /tmp/a.out 
Datei ist lesbar

Program received signal SIGSEGV, Segmentation fault.
0x00005555555548ff in readjobs (fp=0x555555756010, array=0x7fffffffe740, linesToRead=6, facilityCount=6)
    at mat.c:18
18          *array[i] = (int*)malloc(facilityCount * sizeof(int));

好的,所以它在这一行崩溃:

*array[i] = (int*)malloc(facilityCount * sizeof(int));

这样做始终是找出问题所在的好主意。可能是什么原因?不幸的是,在这种情况下,这并不是微不足道的。除非你真的懂指针。*array[i]不是你想要的。你想要(*array)[i]

请记住,这x[i]只是*(x+i). 此外,[]具有比 更高的优先级*。所以*x[i]= *(x[i])= *(*(x+i)),但你想要的是(*x)[i]=*((*x) + i)这显然不是一回事。

其他的东西

我肯定会提取矩阵的创建,如下所示:

int ** createMatrix(int rows, int columns) {
    printf("%d %d\n", rows, columns);
    int **ret;
    ret = malloc(rows * sizeof *ret);
    if(!ret) { perror("Error: "); exit(EXIT_FAILURE); }
    for(int i=0; i<columns; i++) {
        ret[i] = malloc(columns * sizeof (*ret)[0]);
        if(!ret[i]) { perror("Error: "); exit(EXIT_FAILURE); }
    }
    return ret;
}

然后在您的代码中:

*array = createMatrix(rows, facilityCount);
// Don't trust my code. Check the pointer.
if(!array) { perror("Error: "); exit(EXIT_FAILURE); } 

请记住始终检查是否malloc成功。

而且你阅读数字的方式很奇怪。如果你是一个自己想出这个方法的初学者,那实际上是相当令人印象深刻的,但这不是一个好方法。阅读fscanfgetline


推荐阅读