【问题标题】:Segmentation fault while loading big txt.file into C program将大 txt.file 加载到 C 程序中时出现分段错误
【发布时间】:2015-05-17 15:55:24
【问题描述】:

我用 C 语言编写了一个程序。尝试使用我的小 txt 文件作为参数运行它时,我没有问题。不幸的是,当我尝试加载更大的文件时,我遇到了分段错误(核心转储。甚至我的主函数的 1 行也没有执行。这是负责启动和加载 txt 文件作为我的 argv[1] 参数的代码的一部分.我真的不明白问题出在哪里。大 Txt 文件大约 13 MB。我正在使用 linux(ubuntu)。我将不胜感激。

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

typedef struct 
{
    int x;
    int y;
    int wage;   
}Edge;


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

printf("Program starts");


int x,y,z;
int counter = 1;
int N,E;   //node,edges

FILE *fid;   
fid = fopen(argv[1],"r");

fscanf(fid,"%d%d",&N,&E);   

Edge Graph[E];
int visited[N+1];


    while(counter <= E){
        fscanf(fid, "%d%d%d", &x, &y,&z);
        Graph[counter-1].x=x;
        Graph[counter-1].y=y;
        Graph[counter-1].wage=z;
        counter=counter+1;
    }   


printf("\nWe load all edges. Here is our Graph");
fclose(fid) ;  


printf("Program ends");
return 0;


}

【问题讨论】:

  • 如果Graph 变大,尝试使用动态内存分配:Edge* Graph=malloc(E*sizeof(Edge));if(Graph==NULL){printf("malloc failed E=%d\n",E);exit(1)} ...free(Graph);visited 执行相同操作。检查文件是否正确打开if(fid==NULL){printf("unable to open file %s\n",argv[1]);exit(1);}
  • 要找出问题所在,在printf() 语句之后添加fflush(stdout);sdtout 被缓冲。或者使用诸如gdb 之类的调试器。看看*.com/questions/8969665/…

标签: c memory-management segmentation-fault


【解决方案1】:

首先是一些近似值:

  • 使用 13MB 的数据,您的文本文件肯定包含超过 100 万条边(假设节点 x 和 y 平均每个代表 3 位数字后跟一个空格,工资平均 1 位数字后跟一个空格) 和至少 1400 个节点。

  • 您的可变长度数组 Graph[E] 和visited[N+1] 是局部变量,因此存储在堆栈中。假设每个整数有 4 个字节,那么要放入堆栈的数据将超过 12 MB。

您在堆栈上需要的数据量超过了大多数 linux 系统上通常使用的默认堆栈大小 (8 MB)。

您可以考虑增加堆栈大小,如this SO question 中所述。

但你最好考虑动态分配:

Edge *Graph =  calloc (sizeof(Edge),E);
int *visited = calloc (sizeof(int), N+1);
if (Graph==NULL || visited==NULL) {
     printf ("Oops ! Out of memory (%d edges, %d notes) !!", E, N+1); 
     exit (1);   // or some other kind of error handling 
}

【讨论】:

    最近更新 更多