I have an std::vector<SomeType>, whereas SomeType is a struct instantiated from various template parameters.
Eventually in my specific case it turns out to be a large structure (about 1MB). Allocating such a structure on the stack (i.e. using an automatic variable of this type) immediately leads to the stack overflow. But since std::vector allocates the memory on the heap – there should be no problem.
Surprisingly there is a problem with this. Specifically, the problem is with the initialization. I do the following:
std::vector<SomeType> myVec;
// ...
myVec.resize(N);
for (size_t i = 0; i < N; i++)
{
SomeType& x = myVec[i];
// initialize it
}
I get a stack overflow exception in myVec.resize(). Stepping inside resize() with the debugger revealed that if resize() causes the vector to grow – besides of allocating the memory it also initializes the new elements by “default values”.
The “default value” is obtained by creating an automatic variable of the given type, using default (i.e. empty) constructor, and assigning the new element to it.
I wonder if there’s a way to overcome this. I mean, tell std::vector not to initialize the new elements. But I’d like to achieve this without generating unneeded code.
I can think of using a vector of (smart/shared/scoped/unique) pointers to type. Or alternatively use push_back whereas each new element is allocated on heap. But all this inevitable involves extra code. Which is not justified.
Is there a way to achieve what I need? Whereas:
- still using
std::vector<SomeType> - No redundant heap allocations
Thanks in advance
In C++03 it’s impossible:
Therefore you need an element to copy from. It doesn’t fit on the stack (ruling out the default argument) and you don’t want to explicitly put it elsewhere, so you’re out of luck.
In C++11 there are new means of initializing elements in a container, and for example the
size_tconstructor no longer takes an extra default argument. Instead it value-initializes each element, which is probably what you want.So in C++11, the answer is
std::vector<SomeType> myVec(N);. Perhaps you could check whether your compiler has a C++11 mode that you could use to compile your code. Of course, migrating to C++11 isn’t completely trivial.