用C解析大文件

时间:2014-02-28 17:02:09

标签: c linux

对于一个类,我已经被赋予了使用pthreads,openmp和MPI并行编写基数排序的任务。在这种情况下,我选择的语言是C - 我不太了解C ++。

无论如何,我正在阅读文本文件的方式导致文件大小约为500MB的分段错误。这些文件是以行分隔的32位数字:

12351
1235234
12
53421
1234

我知道C,但我不太清楚;我使用我所知道的东西,在这种情况下,我所知道的事情非常低效。我读取文本文件的代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

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

 if(argc != 4) {
   printf("rs_pthreads requires three arguments to run\n");
   return -1;
 }

 char *fileName=argv[1];
 uint32_t radixBits=atoi(argv[2]);
 uint32_t numThreads=atoi(argv[3]);

 if(radixBits > 32){
   printf("radixBitx cannot be greater than 32\n");
   return -1;
 }

 FILE *fileForReading = fopen( fileName, "r" );
 if(fileForReading == NULL){
   perror("Failed to open the file\n");
   return -1;
 }
 char* charBuff = malloc(1024);

 if(charBuff == NULL){
   perror("Error with malloc for charBuff");
   return -1;
 }

 uint32_t numNumbers = 0;
 while(fgetc(fileForReading) != EOF){
   numNumbers++;
   fgets(charBuff, 1024, fileForReading);
 }

 uint32_t numbersToSort[numNumbers];

 rewind(fileForReading);
 int location;
 for(location = 0; location < numNumbers; location++){
   fgets(charBuff, 1024, fileForReading);
   numbersToSort[location] = atoi(charBuff);
     } 

在5000万个数字(~500MB)的文件中,我在所有地方的倒带时遇到了分段错误。我对文件流如何工作的了解几乎不存在。我的猜测是它试图没有足够的内存或其他东西,但我不知道。

所以,我在这里有两个人:倒带分割错误怎么样?我在回放之前做的很差,而不是检查一些系统调用我应该这样做吗?

而且,从文本文件中读取任意数量的数字的更有效方法是什么?

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

我认为这里最可能的原因是(具有讽刺意味的)堆栈溢出。您的numbersToSort数组在堆栈上分配,堆栈具有固定大小(因编译器和操作系统而异,但1 MB是典型数字)。您应该使用numbersToSort在堆上(具有更多可用空间)动态分配malloc()

uint32_t *numbersToSort = malloc(sizeof(uint32_t) * numNumbers);

不要忘记稍后解除分配:

free(numbersToSort);

我还要指出,如果有任何空白行,那么用于计算行数的第一遍循环将失败。这是因为在空白行中,第一个字符为'\n'fgetc()将使用它;下一次调用fgets()将会读取以下行,并且您将跳过计数中的空白行。

答案 1 :(得分:1)

问题出在这一行

uint32_t numbersToSort[numNumbers];

您正在尝试在堆栈中分配一个巨大的数组,您的堆栈大小只有几KB(此外,较旧的C标准不允许这样做)。所以你可以试试这个

uint32_t *numbersToSort; /* Declare it with other declarations */


/* Remove uint32_t numbersToSort[numNumbers]; */
/* Add the code below */
numbersToSort = malloc(sizeof(uint32_t) * numNumbers);
if (!numbersToSort) {
     /* No memory; do cleanup and bail out */
     return 1;
}