在我的项目中,有一百万个输入,我应该比较不同输入数量的搜索/排序算法,直到一百万个输入。我想用数据一起做内存分配和初始化,但我意识到这是不可能的。所以我决定这样做;
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。那么,有没有什么方法可以把这两者结合起来呢?(没有溢出,有数据初始化)
其次,这两个代码之间有什么区别吗?
Person *list[N];
for(i=0; i<N; i++){
list[i] = new Person();
}
Person *list = new list[N];
发布于 2014-10-24 20:16:43
作为初学者,最好避免使用自己的容器。您可以只使用标准提供的:
..。
#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仍然是一个更好的主意)。
发布于 2014-10-24 20:15:58
在您的示例中,
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对象都有一个大小,除了指针数组之外还需要分配。
https://stackoverflow.com/questions/26547533
复制相似问题