C++ 构造函数:当 malloc 分配内存失败时我应该抛出哪种异常类型

Car*_* HR 0 c++ malloc error-handling constructor throw

所以,想象一下我有这个代码:

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;
            }
        }
};
Run Code Online (Sandbox Code Playgroud)

一旦 malloc 在构造函数内分配内存失败,我应该抛出哪种异常?

在这种情况下,我不能简单地 returnfalseNULL。所以throw声明应该是要走的路。

但是,我找不到要抛出的正确类型的异常。我应该抛出一个默认异常吗?或者有没有适合这种情况的?

Hum*_*ler 5

最合适的异常是 throw std::bad_alloc; 但是,malloc除非您有充分的理由,否则强烈建议不要使用- 因此我建议不要明确抛出它。

如果您绝对需要堆内存,则应该使用new/ delete-- 它会自动调用构造函数/析构函数、开始/结束对象生命周期,并std::bad_alloc在内存不足时为您抛出一个。std::malloc将导致任何非平凡类型的未定义行为,因为它没有正式开始对象的生命周期。

更好的是,已经出来十多年了,所以请使用std::unique_ptr,如果您有,请使用,std::make_unique这样您甚至不需要 new直接使用。如果指针不为空unique_ptr,将通过确保delete在分配的指针上调用来防止内存泄漏。

这现在看起来像:

#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>()}
        {

        }
};
Run Code Online (Sandbox Code Playgroud)

除了上面的答案:除非您真的需要具有动态生命周期的对象,否则您不应该真正使用堆内存。在您提供的代码中,看起来Point无论如何只保存按值可能更合适:

class Foo {
    private:
        Point p;
    public:
        Foo () 
          : p{} // no allocation needed
        {

        }
};
Run Code Online (Sandbox Code Playgroud)