在我的项目中,有一百万个输入,我应该将搜索/排序算法与不同数量的输入进行比较,直到一百万个输入。我想用数据一起进行内存分配和初始化,但是我不能实现它。所以我决定这样做;
double temp1, temp2, temp3; //Each line has three numbers
int i;
Person *list[N]; //Here, stackoverflow occurs, for example N=500000
for(i=0; i<N; i++){
file >> temp1 >> temp2 >> temp3;
list[i] = new Person(temp1, temp2, temp3); //I wanted to initialize with data
} //but if I wrote "new Person[N]"
//stackoverflow doesn't occur
但是有大量的溢出,例如N = 500000。
那么,有没有任何方法将这两者结合起来?(没有溢出和数据初始化)
double temp1, temp2, temp3; //Each line has three numbers
int i;
Person *list[N]; //Here, stackoverflow occurs, for example N=500000
for(i=0; i<N; i++){
file >> temp1 >> temp2 >> temp3;
list[i] = new Person(temp1, temp2, temp3); //I wanted to initialize with data
} //but if I wrote "new Person[N]"
//stackoverflow doesn't occur
Person *list[N];
for(i=0; i<N; i++){
list[i] = new Person();
}
答案 0 :(得分:2)
作为初学者,最好避免使用自己的容器。您可以使用标准提供的那些:
...
#include <vector>
#include <cstdlib> // for EXIT_FAILURE, EXIT_SUCCESS
double temp1, temp2, temp3; //Each line has three numbers
std::vector<Person> people;
for(int i=0; i<N; i++)
if (file >> temp1 >> temp2 >> temp3)
people.emplace_back(temp1, temp2, temp3);
else
{
std::cerr << "error reading 3 numbers from file, terminating\n";
exit(EXIT_FAILURE);
}
使用vector
(或new Person[n]
,与new Person*[n]
形成对比)将内存中的数据保持在一起(连续)非常有用,因此您的CPU可以获得在您要比较的搜索和排序过程中,从缓存中获得的最大可能收益...如果您的数据难以访问它,则会隐藏被测算法之间性能差异的程度。在堆上分配new Person*[n]
和每个Person
对象时,数据会分散,访问速度会慢得多。
只是为了解释当前代码发生了什么:
其次,这两个代码之间是否存在差异;
Person* list[N]; // first
for(i=0; i<N; i++){
list[i] = new Person();
}
Person *list = new Person[N]; // second - corrected from "new list[N}"
第一个请求堆栈上的Person*
数组,然后将每个指针分配给不同的动态分配的内存地址。充其量,这将使用几乎尽可能多的堆栈内存 - 最糟糕的是大约两倍 - 试图将Person list[N];
直接放在堆栈上并且可能以相同的方式失败。它还会在动态内存中散布Person
数据,对数据的操作也会不必要地慢。
第二个创建一个动态分配的内存区域,大小足以容纳N
Person
,并在堆栈上保留一个指针。这不是不合理的(但std::vector
仍然是一个更好的主意)。
答案 1 :(得分:0)
在您的示例中,
Person *list[N];
作为堆栈上的局部变量创建。 500,000个指针占用大约2 MB - 这可能会超过某些机器上的堆栈大小。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686774(v=vs.85).aspx
然而,
//Person *list = new list[N];
Person **list = new Person* [N];
将在堆上创建您的数组,您应该能够在不耗尽内存的情况下分配它。但是,除了指针数组之外,每个Person
对象都有一个大小并需要分配。