Search code examples
c++error-handlingconstructormallocthrow

C++ constructor: which exception type should I throw when malloc fails to allocate memory


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?


Solution

  • 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, has been out for over ten years, so use std::unique_ptr and, if you have , 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
            {
    
            }
    };