Reputation: 37
I want to create a unique pointer using unique_ptr<A>(new A)
(not make_unique()
).
The unique_ptr
constructor is noexcept
, however new
may throw bad_alloc
.
So my question is, whether I should expect an exception calling unique_ptr<A>(new A)
in case new
fails or not?
I tried to check that and I'm getting 'abort' in the code below, whereas I expected to see "null"
on the screen. So it seems, that in case new
fails, unique_ptr
will throw an exception.
Is that correct?
class A
{
public:
int vec[1000000000];
};
int main()
{
A* a[100000];
for (int i = 0; i < 100000; ++i)
{
a[i] = unique_ptr<A>(new A).release();
if (!a[i])
{
cout << "null" << endl;
break;
}
}
return 0;
}
Note: The only goal of this code is to cram the memory so that new
fails.
Upvotes: 0
Views: 1438
Reputation: 122133
Suppose you have
void foo(int) noexcept {}
int bar() { throw 42; }
int main(){
foo(bar());
}
Then foo
is not called because already bar()
throws.
So it seems, that in case new fails, unique_ptr will throw an exception.
No, the unique_ptr
constructor is not being called when new
throws.
Upvotes: 2
Reputation: 595742
So my question is, whether I should expect an exception calling
unique_ptr<A>(new A)
in casenew
fails or not?
Yes. If new
fails, it will throw a std::bad_alloc
exception, and the std::unique_ptr
object will not even be constructed at all.
I tried to check that and I'm getting 'abort' in the code below, whereas I expected to see
"null"
on the screen. So it seems, that in casenew
fails,unique_ptr
will throw an exception. Is that correct?
No. new
is the one throwing the exception, not the std::unique_ptr
constructor (which it can't anyway due to being noexcept
, as you noted). Since new
is being called outside of the constructor, the constructor being marked as noexcept
is irrelevant.
If you want to avoid the std::bad_alloc
exception being thrown, use the std::nothrow
version of new
, eg:
#include <new>
a[i] = unique_ptr<A>(new(nothrow) A).release();
Alternatively, since your use of unique_ptr().release()
defeats the whole purpose of std::unique_ptr
, just omit it entirely:
a[i] = new(nothrow) A;
Don't forget to delete
whatever is successfully new
'ed.
Upvotes: 4