So, imagine I have this code:
typedef struct Point {
float x;
float y;
} Point;
class Foo {
private:
Point * p;
public:
Foo () {
this->p = (Point *) malloc(sizeof(Point));
if (this->p == NULL) {
// throw exception_malloc_fail;
}
}
};
Which kind of exception should I throw once malloc fails allocating memory inside a constructor?
In this kind of situation, I cannot simply return false
or NULL
. So a throw
statement should be the way to go.
However, I cannot find the correct type of exception to throw. Should I just throw a default exception? Or is there one appropriate for this kind of situation?
The most appropriate exception would be to throw std::bad_alloc
; however it is strongly discouraged to use malloc
unless you have a good reason to -- and so I would advise against throwing this explicitly.
If you absolutely need heap memory, you should be using new
/delete
-- which will automatically invoke constructors/destructors, start/end object lifetimes, and will throw a std::bad_alloc
when out of memory for you. std::malloc
will result in undefined behavior for any non-trivial types because it doesn't formally start an object's lifetime.
Better yet, c++11 has been out for over ten years, so use std::unique_ptr
and, if you have c++14, use std::make_unique
so you don't even need new
directly. unique_ptr
will prevent memory leaks by ensuring that delete
is called on the allocated pointer if the pointer is not-null.
This would now look like:
#include <memory>
// Note: 'typedef struct' does nothing in C++ -- there is no need for it
struct Point {
float x;
float y;
};
class Foo {
private:
std::unique_ptr<Point> p;
public:
Foo ()
: p{std::make_unique<Point>()}
{
}
};
Aside from the above answer: You shouldn't really use heap memory unless you really have a need for objects with dynamic lifetime. In the code you provided, it looks like it may be more appropriate to just hold the Point
by value anyway:
class Foo {
private:
Point p;
public:
Foo ()
: p{} // no allocation needed
{
}
};