Stack overflow with std :: make_unique, but not with raw pointer
I would like to highlight a large object (a bitset<1000000000>
). Since ownership of original pointers should be avoided, I tried the following declaration:
auto foo()->std::unique_ptr<std::bitset<MAX>>;
...
{
auto bar = foo();
}
which gives an error (VS2013 compiler). But
auto foo()->std::bitset<MAX>*;
...
{
auto bar = foo();
...
delete bar;
}
not.
The implementation foo()
looks like this:
auto is_prime =
//std::make_unique<std::bitset<MAX>>(std::bitset<MAX>{});
// or:
new std::bitset<MAX>{};
is_prime->set();
(*is_prime)[0] = (*is_prime)[1] = false;
auto max_i = static_cast<int>(std::sqrt(MAX)) + 1;
for (auto i = 1; i < max_i; i++) {
if ((*is_prime)[i]) {
for (auto j = i * i; j < MAX; j += i) {
(*is_prime)[j] = false;
}
}
}
return is_prime;
What is the obvious thing am I missing?
source to share
auto is_prime =
std::make_unique<std::bitset<MAX>>(std::bitset<MAX>{});
This line creates a temporary bit ( std::bitset<MAX>{}
) object on the stack and then passes it to the copy constructor of the new
-ed object on the heap.
To just use the default constructor, you want:
auto is_prime = std::make_unique<std::bitset<MAX>>();
source to share
When you use
typdef std::bitset<1000000> BS;
std::make_unique<BS>(BS())
you're creating a pretty sizable object on the stack: a copyable temporary object! Depending on how much tve you already have on the stack or how large the stack is, this can easily cause a stack overflow. There is no temporary tge stack for the direct memory allocation operation.
The simple solution to the problem is to simply use
std::make_unique<BS>()
as this should result in a default constructor for the allocated heap object.
source to share