Reputation: 529
In my project, there are one million inputs and I am supposed to compare search/sort algorithms with different numbers of inputs untill one million inputs. I want to do memory allocation and initialization with data together but I reailized it is not possible. So I decided to do like this;
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
But there is an overflow with huge numbers, for example N = 500000.
So, is there any method which combine these two?(Without overflow and with data initialization)
Person *list[N];
for(i=0; i<N; i++){
list[i] = new Person();
}
Person *list = new list[N];
Upvotes: 0
Views: 408
Reputation: 106096
As a beginner, it's best to avoid using your own containers. You can just use the Standard-provided ones:
...
#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);
}
It's especially useful to use vector
(or new Person[n]
, and in contrast to new Person*[n]
) to keep the data together (contiguous) in memory, so your CPU gets the maximum possible benefit from its caches during the searching and sorting that you want to compare... if your data's harder to access it'll hide the extent of performance difference between the algorithms under test. With new Person*[n]
and every Person
object being allocated on the heap, the data gets scattered and can be much slower to access.
Just to explain what was happening with your current code:
Secondly, is there any difference between these two code;
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}"
The first asks for an array of Person*
s on the stack, then assigns each of those pointers to a distinct dynamically-allocated memory address. At best, that will use almost as much stack memory - and at worst around double - as trying to put Person list[N];
directly on the stack and is likely to fail the same way. It also scatters the Person
data around in dynamic memory, and operations on the data will be unnecessarily slow.
The second creates one dynamically-allocated memory region big enough for N
Person
s, and keeps a single pointer to it on the stack. That's not unreasonable (but std::vector
's still a better idea).
Upvotes: 2
Reputation: 6171
In your example,
Person *list[N];
is created as a local variable on the stack. 500,000 pointers would take up about 2 MB - which is likely to exceed the stack size on some machines. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686774(v=vs.85).aspx
However,
//Person *list = new list[N];
Person **list = new Person* [N];
will create your array on the heap, and you should be able to allocate that without running out of memory. However, each Person
object will have a size and require allocation in addition to the array of pointers.
Upvotes: 0