【问题标题】:Multidimensional array segfault and 139 (0x8B) return多维数组段错误和 139 (0x8B) 返回
【发布时间】:2016-04-17 22:40:45
【问题描述】:

我正在尝试分配一个多维数组以从文件中读取信息,然后打印它以检查它是否正常工作,然后将数组信息获取到二维数组(尚未完成)。但是由于某种原因,它给了我段错误并返回 139 (0x8B),当我运行它并尝试调试它时,它会打印所有内容,但最后它说它无法打开文件:lib-start.c。提前谢谢!

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

    int ***getFileLoad (char *nomeFicheiro);
    int ***InitArray (int ***array, int cells);
    void freeArray(int ***array, int cells);

    int main () {

    int ***intArray=NULL, intCells;
    char strNome[10], *p2String=NULL;

    printf("Nome ficheiro: ");
    scanf("%s", strNome);

    p2String=strNome;

    intArray=getFileLoad(p2String);

    intCells=intArray[1][0][0];   /*intCells+2 -> nr of lines to read from the file*/

    freeArray(intArray, intCells);

    return 0;
}

int ***getFileLoad (char *nomeFicheiro) {

    char strLines[5], strColumns[5], strCells[5], strTemp[3];
    int i=0, j=0, k=0, b=2, lines=0, columns=0, cells=0, intTemp=0;
    int ***array=NULL;
    FILE *ficheiro=NULL;

    ficheiro=fopen(nomeFicheiro, "r");   /*open file*/

    if (ficheiro==NULL) {
        printf("Erro ao abrir o ficheiro!\n");
        exit(EXIT_FAILURE);
    }

    fscanf(ficheiro, "%s %s %s", strLines, strColumns, strCells);

    if ((lines=atoi(strLines))<=0) {    
        printf("Invalid nr of lines!\n");
        exit(EXIT_FAILURE);
    }

    if ((columns=atoi(strColumns))<=0) {      
        printf("Invalid nr of columns!\n");
        exit(EXIT_FAILURE);
    }

    if ((cells=atoi(strCells))<=0) {
        printf("Invalid nr of cells!\n");
        exit(EXIT_FAILURE);
    }

    array=InitArray(&array, cells);

    array[0][0][0]=lines;
    array[0][1][0]=columns;
    array[1][0][0]=cells;


    for (i=2 ; i<cells+b ; i++) {       /*nr of lines to read*/
        for (j=0 ; j<1 ; j++) {         /*last value*/
            for (k=0 ; k<4 ; k++) {     /*middle value*/
                if (k==3) {             /*check if there is something else that I don't want on the Array*/
                    intTemp=fgetc(ficheiro);
                    if (intTemp=='\n' || intTemp==EOF) {
                        continue;
                    } else {
                        while(intTemp!='\n' || intTemp!=EOF) {
                            intTemp=fgetc(ficheiro);
                            if (intTemp=='\n' || intTemp==EOF) {
                                break;
                            }
                        }
                    }
                } else {
                    fscanf(ficheiro, "%s", strTemp);

                    if (isdigit(strTemp)) {
                        intTemp=atoi(strTemp);
                        if (k==0) {             /*accepts lines between 1->lines*/
                            if (!(intTemp>=1 && intTemp<lines)) {
                                printf("Invalid values!\n");
                                exit(EXIT_FAILURE);
                            } else {
                            array[i][k][j]=intTemp;
                            }
                        } else if (k==1) {      /*accepts columns between 1->columns*/
                            if (!(intTemp>=1 && intTemp<columns)) {
                                printf("Invalid values!\n");
                                exit(EXIT_FAILURE);
                            } else {
                            array[i][k][j]=intTemp;
                            }
                        } else if (k==2) {      /*accepts cells with values between 0->2*/
                            if (!(intTemp>=0 && intTemp<3)) {
                                printf("Invalid values!\n");
                                exit(EXIT_FAILURE);
                            } else {
                            array[i][k-1][j+1]=intTemp;
                            }
                        }
                    }
                }
            }
        }
    }

    intTemp=fgetc(ficheiro);   /*checking for EOF*/

    if (intTemp!=EOF) {
        printf("EOF not detected!\n");
        exit(EXIT_FAILURE);
    }

    fclose(ficheiro);

    return array;
}

int ***InitArray (int ***array, int cells) {

    int b=2, i=0, j=0, k=0 , l=0;

    array=(int ***)malloc((cells+b)* sizeof(int**));    /*allocating 3D array*/

    if (array==NULL) {
        printf("Not enough memory!\n");
        exit(EXIT_FAILURE);
    }

    for(i=0 ; i<cells+b ; i++) {
        (array)[i]=(int **)malloc(b* sizeof(int*));

        if ((array)[i]==NULL) {
            printf("Not enough memory!\n");
            for (j=0 ; j<i ; j++) {
                free((array)[j]);
            }
            free(array);
            array=NULL;
            exit(EXIT_FAILURE);
        }


        for (j=0 ; j<b ; j++) {
            (array)[i][j]=(int*)malloc(b*sizeof(int));

            if ((array)[i][j]==NULL) {
            printf("Not enough memory!\n");
            for (k=0 ; k<i ; k++) {
                for (l=0 ; l<j ; l++) {
                    free((array)[k][l]);
                }
            }
            free(array);
            array=NULL;
            exit(EXIT_FAILURE);
            }
        }
    }

    return array;
}

void freeArray(int ***array, int cells) {

    int i, j, b=2;

    for (i=0 ; i<cells+b ; i++) {
        for (j=0 ; j<b ; j++) {
            free((array)[i][j]);
        }
        free((array)[i]);
    }
    free(array);
    array=NULL;

}

文件示例:

22 40
4
1 2 1
1 3 1
1 4 1
1 5 1

【问题讨论】:

  • intArray=getFileLoad(p2String); 嗯? int 返回到 int ***?
  • @SouravGhosh,我的错……更新它
  • @RSahu,你是什么意思?
  • 如果要返回整数数组,请使用int * 而不是int ***。我什至不确定最后一个返回什么。指向指向 int 的指针的指针?

标签: c multidimensional-array segmentation-fault allocation


【解决方案1】:

该程序在我的系统上运行良好:Linux Fedora 22 g++ 5.1.1 没有SEGFAULT

我还使用 valgrind

检查了内存泄漏和无效内存访问
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./StackQuestion

(抑制:0 从 0)

==6904== LEAK SUMMARY:
==6904==    definitely lost: 0 bytes in 0 blocks
==6904==    indirectly lost: 0 bytes in 0 blocks
==6904==      possibly lost: 0 bytes in 0 blocks
==6904==    still reachable: 72,704 bytes in 1 blocks
==6904==         suppressed: 0 bytes in 0 blocks
==6904== 
==6904== For counts of detected and suppressed errors, rerun with: -v
==6904== ERROR SUMMARY: 0 errors from 0 contexts

表示没有进行无效访问,只有一次无害的内存泄漏(无害的,因为操作系统会在进程终止时正确回收该内存)。

关于 lib_start 我的猜测是您在 GDB 中设置了一个断点,或者您正在尝试调试一些基本上不可调试的函数,如 read() 或其他读取/写入文件的函数.这些功能需要内核帮助才能完成这种事情(显然 GDB 无法调试)。

我想我们需要更多信息来重现奇怪的行为,例如 g++ 版本、操作系统和您传递给程序的文件。

【讨论】:

  • 现在开始工作了!像你一样使用 Valgrind,它在 isdigit(strTemp) 上给了我一个错误。谢谢大佬!
  • 哦,但我坚持很明显有 2 个错误。 isdigit 应该与 stoi 一起使用,并且 initarray 的参数是错误的。很高兴它有帮助。请将问题标记为已回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
相关资源
最近更新 更多