首页 > 解决方案 > 如果我在没有新表达式的情况下直接调用 operator new 并将返回指针类型转换为安全的?

问题描述

您好,我在 C++ 入门第 5 版的第 19 章。' Operator newand deletevs newanddelete表达式和位置new':

AFAIKoperator newoperator delete 分别分配和释放内存,但不在那里构造对象。另一方面,new-expression调用operator new分配内存,在该内存地址中构造一个对象,最后返回一个指向新分配和初始化的对象的指针。

所以为了理解起见,我试过这个:

struct Foo{
    Foo(){std::cout << "Foo()\n";}
    ~Foo(){std::cout << "~Foo()\n";}
    void bar() const{
        std::cout << "Foo::bar()\n";
    }
};

int main(){


    Foo* pf = (Foo*)operator new(sizeof(Foo)); // Foo() is not called! Is it UB?
    pf->bar(); // looks to work fine. Does it really?
    delete pf; // looks fine?


    Foo* pf2 = new Foo{}; // ok Foo() is called 
    pf2->bar(); // OK
    delete pf2; // OK ~Foo() is called

}

正如您在第一个示例中看到的那样,我直接调用了 operator new,我猜后者只分配内存但不在那里构造对象,最后它返回一个指向 void 的指针,指向新分配的成员。

所以我没有调用构造函数Foo()。现在为什么调用成员函数可以正常工作?pf->bar()? 还是这会产生未定义的行为?

第二个例子 ( pf2) 很简单。

标签: c++new-operatordelete-operatornew-expression

解决方案


除非你使用placement new(基本上是普通的另一半new),否则不Foo存在对象,所以你不能在它上面调用成员函数。此外,如果你使用placement new,你必须自己调用析构函数:

Foo* pf = new (operator new(sizeof(Foo))) Foo;  // no cast needed
pf->bar();
pf->~Foo();
operator delete(pf);  // analogous, though not equivalent, to std::free

推荐阅读