我写了一个简单的插入排序实现来试图破坏生锈,并开始我希望通常更好地理解algortihms。该文件包含2000万个随机数。代码如下:
#include <fstream>
#include <time.h>
#include <cstdlib>
using namespace std;
void insertionSort(double numbers[], int array_size);
int main() {
int count;
double twentyMMNumbers[20000000];
ifstream inputFile;
time_t now;
time(&now);
inputFile.open("20KRandomsNumbers.data"); //Opens input file
if(inputFile.fail())
{
printf("Cannot open inputFile");
exit(1);
}
count = 0;
printf("%d\n",count);
inputFile >> twentyMMNumbers[count];
printf("%f\n",twentyMMNumbers[count]);
while(inputFile)
{ //While loop
count++;
if(count < 20000000)
inputFile >> twentyMMNumbers[count];
}
inputFile.close();
printf("%s\n", ctime(&now)); //BEFORE
insertionSort(twentyMMNumbers, 20000000); //Insertion Sort 20KRandomNumbers
printf("%s\n", ctime(&now)); //AFTER
for(int i = 0; i < count; i++)
printf("%f\n",twentyMMNumbers[i]);
}
void insertionSort(double numbers[], int array_size)
{
int i, j, index;
for (i=1; i < array_size; i++)
{
index = numbers[i];
j = i;
while ((j > 0) && (numbers[j-1] > index))
{
numbers[j] = numbers[j-1];
j = j - 1;
}
numbers[j] = index;
}
}
当代码只有20,000个条目时,代码工作正常,但现在给了我:
Segmentation fault: 11
这是由于我增加了数组的大小吗? 如果您有任何关于优化此功能的提示,请随时指出。
答案 0 :(得分:2)
讽刺的是(给定这个站点名称),你有一个堆栈溢出。您需要在堆上动态分配那么多内存。
为了更清晰,这一行:
double twentyMMNumbers[20000000];
需要
double* twentyMMNumbers = (double*)malloc(20000000*sizeof(double));
当然,在退出程序之前,您需要释放内存(作为最佳做法):
free(twentyMMNumbers);
答案 1 :(得分:2)
它适用于较小的数组大小,所以这里有一些注释(因为它在CodeReview上)和一些更大的数组大小的修复。
1,如果要使用固定大小的数组,请使用常量而不是200000
(或20000000
)文字。
2,使用动态数组更好。在读完第一行后分配内存,并使用readed大小作为新数组的大小。此外,我会将数据文件的大小(文件的第一行)存储在一个单独的变量中,而不是存储在数组中。
int dataSize;
inputFile >> dataSize;
double *twentyMMNumbers = new double[dataSize];
它分配确切的内存量。不多也不少。
它还修复了 Segmentation fault 错误。有关更多信息,请查看以下问题:Segmentation fault on large array sizes
(不要忘记使用delete[]
取消分配数组。)
3,如果记录的数量多于数组的大小,则无需读取整个文件。我修改了while循环:
while (inputFile) {
if (count >= dataSize) {
break;
}
inputFile >> twentyMMNumbers[count];
count++;
}
inputFile.close();
也许exit(-1)
和错误消息会更好,而不是break
。
4,以下评论是不必要的:
//While loop
5,你应该将数组的实际大小传递给insertionSort
函数,所以写下:
insertionSort(twentyMMNumbers, dataSize);
此处的评论也是不必要的。
6,改进错误处理:dataSize
的值大于文件中的数字时会发生什么?
7,我会使用最后一个printArray
循环和一个for
函数提取readInput
函数。
8,考虑使用C ++样式打印而不是printf
s:
cout << "Hello world!" << endl;
(#include <iostream>
是必需的。)
答案 2 :(得分:1)
你的while循环中有问题:
while(inputFile)
{ //While loop
count++;
if(count < 20000000)
inputFile >> twentyMMNumbers[count];
}
仅当文件包含&lt; = 20000000个数字时,此循环才会终止。如果count变为20000000,它将不再尝试从inputFile
读取,但仍然使用inputFile
作为继续循环的条件。然后当count达到最大int
值时,它会回绕,你将使用负数索引twentyMMNumbers
。这很可能是您遇到分段错误的原因。
20000000是代码中的“神奇数字”。
,而不是在文件开头都有const int NumElements = 20000000
的地方写下来