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?

+3


source to share


2 answers


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>>();

      

+11


source


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.

+1


source







All Articles