Domanda

C++'s new has an option to return a null pointer instead of throwing a bad_alloc exception when an allocation failed.

Foo * pf = new(std::nothrow) Foo(1, 2, 3);

(Yes, I understand this only prevents the new from throwing a bad_alloc; it doesn't prevent Foo's constructor from throwing an exception.)

If you want to use a shared pointer instead of a raw pointer, you generally should use make_shared, as it gets clever about the allocation of the control block.

auto pf = std::make_shared<Foo>(1, 2, 3);

make_shared encapsulates the new, which makes it impossible(?) to choose the nothrow version. So it seems you have to abandon make_shared and call new explicitly.

std::shared_ptr<Foo> pf(new(std::nothrow) Foo(1, 2, 3));

This eliminates the optimization of allocating the control block with the Foo, and the control block allocation could fail independently of the Foo allocation, but I don't want to focus on that. Let's assume the control block is small so its allocation will never fail in practice. It's the failure to allocate space for the Foo that concerns me.

Is there a way to get the single-allocation advantage of make_shared while retaining the ability to simply get a null pointer instead of a bad_alloc exception when allocating space for the Foo?

È stato utile?

Soluzione

It looks like allocate_shared, passing in an allocator that uses the nothrow new should do the trick for you.

Altri suggerimenti

Just have a custom nake_foo and catch the exception:

#include <memory>

struct Foo {
    Foo(int, int, int) { throw std::bad_alloc(); }
};

std::shared_ptr<Foo> make_foo(int a, int b, int c) {
    try { return std::make_shared<Foo>(a, b, c); }
    catch (const std::bad_alloc&) { return std::shared_ptr<Foo>(); }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top