我正在尝试通过我在 C 中创建的函数从 .csv 文件读取 double 据。 我已经用许多文件测试了该程序,直到 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 循环内,但我不明白为什么。有任何想法吗? 提前致谢
最佳答案
您有整数溢出。我认为你的 int
必须是 32 位,因为否则你就不需要使用
long int len;
用于内存计算
len = (*numObjs) * (*numCoords);
根据您提供的数字计算得出:200000000 * 20 = 4000000000
。这是作为 int
计算(操作数的类型)执行的,在被分配给 len
之前,并且乘积超出范围32 位int
。
您需要先转换其中一个操作数:
len = (long int)(*numObjs) * (*numCoords);
或使用无符号
类型。
关于c - 在c中读取巨大的CSV文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41268962/