0

在我的项目中,有 100 万个输入,我应该将搜索/排序算法与不同数量的输入进行比较,直到达到 100 万个输入。我想用数据一起进行内存分配和初始化,但我意识到这是不可能的。所以我决定这样做;

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];

4

2 回答 2

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}"

第一个请求堆栈上的 s 数组Person*,然后将这些指针中的每一个分配给不同的动态分配的内存地址。充其量,这将使用几乎与尝试直接放在堆栈上一样多的堆栈内存 - 最坏的情况是两倍左右 -Person list[N];并且可能以同样的方式失败。它还将Person数据分散在动态内存中,对数据的操作将不必要地变慢。

第二个为N Persons 创建一个足够大的动态分配内存区域,并在堆栈上保留一个指向它的指针。这不是不合理的(但std::vector仍然是一个更好的主意)。

于 2014-10-24T12:16:42.730 回答
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但是,除了指针数组之外,每个对象都有一个大小并需要分配。

于 2014-10-24T12:15:57.800 回答