c++ - 如果我在没有新表达式的情况下直接调用 operator new 并将返回指针类型转换为安全的?
问题描述
您好,我在 C++ 入门第 5 版的第 19 章。' Operator new
and delete
vs new
anddelete
表达式和位置new
':
AFAIKoperator new
和operator delet
e 分别分配和释放内存,但不在那里构造对象。另一方面,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
) 很简单。
- 如果一个是安全和正确的,发生了什么?我怎么能使用未初始化的对象?谢谢!
解决方案
除非你使用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
推荐阅读
- python - 如何打印不同行的列表列表?
- android - 使用媒体播放器流式传输 mp3 时出错
- github - 有没有办法在 GitHub 中强制执行分支合并限制?
- css - CSS边框与文本间隙而不改变背景
- python - 使用递归计算数组组合
- jquery - 类型错误 undefined thumnail_path 未定义
- python - 如何在 Windows 系统上执行 Kaggle Api 命令?
- java - 如何将arraylist作为整数返回
- machine-learning - 尽管种子值不同,但 Weka 的预测结果一致
- javascript - 如何解决运行时错误:this.initializationApp 不是函数(对不起英语,我是巴西人)