#include <new>
class Foo {
public:
int *x;
mutable size_t count {1};
Foo() : x {new int} {}
Foo(const Foo &rhs) : x {new int} {
if(++rhs.count > 5) {
throw runtime_error("");
}
}
~Foo() {
delete x;
}
Foo &operator=(const Foo &) = delete;
};
int main(int argc, char *argv[]) {
Foo *p {reinterpret_cast<Foo *>(::operator new (sizeof(Foo) * 5))};
Foo f;
for(auto i {0}; i < 5; ++i) {
try {
new (p + i) Foo(f);
}catch(...) {
for(auto j {0}; j < i; ++j) { //!
(p + j)->~Foo();
}
}
}
::operator delete (p);
}
Please attention to for(auto j {0}; j < i; ++j)
in catch(...) {}
.
In this code, I can change the for
's condition to j <= i
to avoid memory leak. But if p
is in a template container, the revision before may cause UB. Because p + i
hasn't been constructed completely, destructing it directly will cause undefined behaviour.
Is there any way to avoid it, or it is a responsibility for class designer?