对于一个类,我已经被赋予了使用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)的文件中,我在所有地方的倒带时遇到了分段错误。我对文件流如何工作的了解几乎不存在。我的猜测是它试图没有足够的内存或其他东西,但我不知道。
所以,我在这里有两个人:倒带分割错误怎么样?我在回放之前做的很差,而不是检查一些系统调用我应该这样做吗?
而且,从文本文件中读取任意数量的数字的更有效方法是什么?
感谢任何帮助。
答案 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;
}