Lin*_*gxi 7 c++ new-operator dynamic-memory-allocation delete-operator c++14
小心翼翼,这可能不太好.根据cppref:
如果expression是其他任何东西,包括它是否是由new-expression的数组形式获得的指针,则行为是未定义的.
把它放在一边,实际上是下面的代码OK(T非数组,假设new没有替换)?
auto p = (T*)operator new(sizeof(T));
new(p) T{};
delete p;
Run Code Online (Sandbox Code Playgroud)
据说在cppref中
当调用分配功能,新的表达通过请求作为第一个参数,类型的字节数
std::size_t,而这正是sizeof(T)对于非数组T.
所以我想这可能还行.但是,据说从C++ 14开始,
允许新表达式忽略或组合通过可替换分配函数进行的分配.在省略的情况下,存储器可以由编译器提供而不需要调用分配函数(这也允许优化掉未使用的new-expression).在组合的情况下,如果满足以下所有条件,则可以扩展由新表达式E1进行的分配以为另一个新表达式E2提供额外的存储:[...]
请注意,只有在使用new-expression时才允许此优化,而不是任何其他方法来调用可替换的分配函数:
delete[] new int[10];可以优化,但operator delete(operator new(10));不能.
我不太确定其含义.那么,这在C++ 14中可以吗?
我为什么问这个问题?(来源)
有时,内存分配和初始化无法在一个步骤中完成.您必须手动分配内存,执行其他操作,然后初始化对象,例如,以提供强大的异常安全性.在这种情况下,如果删除表达式无法在结果指针上使用,则必须手动取消初始化和取消分配,这很乏味.更糟糕的是,如果使用新表达式和手动方法,则必须跟踪每个对象使用哪一个.
如果您有,则此代码具有明确定义的行为p = new(p) T{};,假设没有自定义(取消)分配函数在起作用。(它可以很容易地针对此类事情进行强化;这样做可以作为读者的练习。)
规则是,您必须为非数组提供delete一个指向由非数组创建的对象的指针new(或此类对象的基类(带有虚拟析构函数)子对象,或空指针)。通过这一更改,您的代码就可以做到这一点。
不要求非数组new是非放置形式。不可能有,因为你最好能够删除new(std::nothrow) int。这也是一种新的展示位置表达方式,尽管人们在谈论“新的展示位置”时通常并不是这个意思。
delete被定义为导致对释放函数的调用(忽略省略情况,这在这里无关紧要,因为 new 表达式调用的唯一分配函数不是可替换的全局分配函数)。如果您进行设置,使其将无效参数传递给该释放函数,那么您会从中得到未定义的行为。但这里它传递了正确的地址(如果使用了大小释放函数,则传递了正确的大小),因此它是明确定义的。