Calling the constructor of a large array of objects on a stack
I'm modifying some C++ source code and I've noticed the author really went out of their way to allocate everything on the stack. Most likely for the deallocation benefits (are there any performance benefits as well??).
I want to keep the same consistency but I need to create a large array of objects and something like:
Object os[1000] = {Object(arg), Object(arg), ....};
isn't going to cut it. Searching around it seems like a way around this is just:
vector<Object> os(1000, Object(arg));
This still allocates on the heap but deallocates like a stack (from what I've read in other posts). I'm just wondering are there any other options because this just seems like a开发者_开发技巧 syntax issue. Perhaps a clever #define people know.
The stack shouldn't be used for large blocks of memory. You simply have to pay the higher price of heap allocation in exchange for the benefit of accessing more memory. Another option is declaring an array with static storage duration, but that has other drawbacks (not re-entrant, not thread-safe). Everything is a tradeoff.
In any case, when allocating complex objects, the cost of calling 1000 constructors will dwarf the time spent in the allocator. Just use std::vector
unless you have profiler data that shows a performance problem.
Yes, there are other options. You can use something like alloca
. This will get you stack allocation and automatic free, but not automatic construction or destruction. You would need to use placement new and explicit invocation of the destructors.
Yes, there may be a performance advantage, but you're also begging to blow the stack, and this pattern is not exception safe like the vector
solution would be (that is, if the object your allocating has a non-trivial destructor).
Allocating large amounts of data on the stack is, generally speaking, a bad idea. The stack on most operating systems is a scratch space and fairly limited in size. Allocating a large amount of stack space for objects can quickly consume all your available stack space, resulting in a segfault or other exception when something attempts to allocate just one more thing on the stack (for instance, a return address for a function call).
As far as other options, you have a few.. std::vector as you've already noticed, along with boost::array are to such examples.
This ought to work:
Object os[1000];
os[0] = Object(args);
std::copy(os, os + 999, os + 1);
This creates the array, initializes one object, then loops through, initializing each element with the last one.
Of course, you probably shouldn't use this. It seems like a bad idea even if it works, and even if Object os[1000]
doesn't cause you problems.
精彩评论