在c中读取巨大的CSV文件

时间:2016-12-21 17:53:22

标签: c file csv

我正在尝试通过我在C中创建的函数从.csv文件中读取双数据。  我用多个文件测试了程序,直到100000000行和20列(文件大小约为14.5 GB)我没有遇到任何问题,但是如果我插入一个包含200000000行和20列的更大文件,我会得到一个分段故障。  我在一个拥有52 GB内存的系统中运行该程序,因此对于这些文件来说它足够大了。 对于我使用的编译:  gcc read_files.c -D_FILE_OFFSET_BITS = 64  在执行之前我也使用了ulimit -a unlimited。

代码是:

double** file_read(char *filename,int  *numObjs,int  *numCoords,int line_length, int lines_to_skip,int attr_to_skip) 
{
    double **objects;
    long int     i, j, len;
    ssize_t numBytesRead;
    int done=0; 
    FILE *infile;
    char *line, *ret;
    char * pch;

    if ((infile = fopen(filename, "r")) == NULL) {
            fprintf(stderr, "Error: no such file (%s)\n", filename);
            return NULL;
    }

    line = (char*) malloc(line_length);

    len = (*numObjs) * (*numCoords);

    objects    = (double**)malloc((*numObjs) * sizeof(double*));
    objects[0] = (double*) malloc(len * sizeof(double));
    for (i=1; i<(*numObjs); i++)
        objects[i] = objects[i-1] + (*numCoords);

    for(i=0;i<lines_to_skip;i++)
       fgets(line, line_length, infile);

    i=0;
    j=0;

    while (fgets(line, line_length, infile) != NULL && i<*numObjs ) 
    {     
             pch=strtok(line, ",;");
             while (pch != NULL && j<(*numCoords))
             {
                objects[i][j]=atof(pch);
                pch = strtok (NULL, ",;");
                j++;
             }
             i++;
             j=0;
             done=0;
    }


    fclose(infile);
    free(line);


    return objects;
}

经过多次测试,我确信分段故障发生在while循环内部,但我无法理解为什么。有任何想法吗? 提前致谢

1 个答案:

答案 0 :(得分:3)

你有整数溢出。我认为你的int必须是32位,否则你不需要使用

long int len;

用于记忆计算

len = (*numObjs) * (*numCoords);

您提供的数字计算为200000000 * 20 = 4000000000。这是作为int计算(操作数的类型),分配给len之前执行的,并且产品超出了32位{{1 }}

您需要首先投射其中一个操作数:

int

或使用len = (long int)(*numObjs) * (*numCoords); 类型。