Reputation: 414
Let's say I have a class that looks like this:
Class A{
private:
int* A1;
int* A2;
public:
A(): A1(new int[1000]), A2(new int[1000]){}
~A(){delete[] A1; delete[] A2;}
}
I want to deal with a situation where the first allocation succeeds and the second fails, and std::bad_alloc
is thrown.
From what I gather, the destructor won't be called because the object was not created successfully.
This can be dealt with if I instead do:
A(): A1(new int[1000]), A2(new(nothrow) int[1000]){}
Then I will be able to deal with this case without exceptions.
However, from what I read nothrow
is very rarely used. I am not sure how exception can be used in this case.
Many thanks.
Upvotes: 0
Views: 130
Reputation: 29193
I would use std::unique_ptr
.
class A {
std::unique_ptr<int[]> A1, A2;
public:
A() : A1(std::make_unique_for_overwrite<int[]>(1000)), A2(std::make_unique_for_overwrite<int[]>(1000)) { }
// if A1 succeeds and A2 fails, A1 is freed
// default no-body destructor works fine
};
But if you really want raw pointers, you can squish the logic into a chain of delegating constructors.
class A {
int *A1, *A2;
A(int *A1) try : A1(A1), A2(new int[1000]) { }
catch(...) { delete[] A1; } // handle A2 fails but A1 success; automatically rethrows (note: accessing members in this catch clause is UB, but we have the constructor parameter)
public:
A() : A(new int[1000]) { }
// any exception in first allocation is immediately thrown here
// any exception in second allocation bubbles up through here after being rethrown
~A() { delete[] A1; delete[] A2; }
};
Upvotes: 1