E
ES Kim
It's a common practice that you throw an exception in a constructor
when the invariant of the class is not met. But what if it's combined
with auto_ptr? I mean:
#include <memory>
using namespace std;
struct S
{
S(int i) { if (i < 0) throw "oops"; }
};
int main()
try
{
auto_ptr<S> ap(new S(-1)); // A
}
catch (...)
{
}
Statement A can be considered step by step like this:
(1) raw memory is allocated by :perator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory
But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.
What is a proper way to solve this kind of problem?
Let's not consider the possibility of bad_alloc. (If a bad_alloc
is thrown, there's no leak at least.)
when the invariant of the class is not met. But what if it's combined
with auto_ptr? I mean:
#include <memory>
using namespace std;
struct S
{
S(int i) { if (i < 0) throw "oops"; }
};
int main()
try
{
auto_ptr<S> ap(new S(-1)); // A
}
catch (...)
{
}
Statement A can be considered step by step like this:
(1) raw memory is allocated by :perator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory
But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.
What is a proper way to solve this kind of problem?
Let's not consider the possibility of bad_alloc. (If a bad_alloc
is thrown, there's no leak at least.)