删除未使用新表达式构建的对象实际上可以吗?
Is it practically OK to delete object not constructed using the new expression?
,这可能不行。根据cppref:
如果表达式是其他任何东西,包括它是通过新表达的数组形式获得的指针,则该行为是未定义的。
将其抛在一边,实践中的以下代码是否正常(T
是非阵列,并且假设new
未替换(?
auto p = (T*)operator new(sizeof(T));
new(p) T{};
delete p;
据说在cppref中
调用分配函数时,新表达通过 要求作为第一个参数的字节数,类型
的std::size_t
,这是非阵列t。sizeof(T)
所以我想这可能还可以。但是,也有人说,由于C 14,
允许新的表达来进行或组合分配 通过可更换的分配功能。如果出现, 编译器可以提供存储,而无需致电 分配功能(这也允许优化未使用的 新表达(。在合并的情况下,由 新表达E1可以扩展以提供额外的存储空间 另一个新表达E2如果以下所有内容都是正确的:[...]
请注意,只有在新表达时才允许此优化 使用的,没有任何其他可以调用可更换分配功能的方法:
delete[] new int[10];
可以优化,但operator delete(operator new(10));
不能。
我不太确定含义。那么,在C 14中可以吗?
我为什么要问这个问题?(source(
有时,内存分配和初始化无法在一个步骤中完成。您必须手动分配内存,做其他事情,然后初始化对象,例如,提供强大的例外安全性。在这种情况下,如果无法在结果指针上使用删除表达式,则必须手动不启用和划分,这很乏味。为了使事情变得更糟,如果采用新表达方式和手动方法,您必须跟踪每个对象使用的一个。
如果您具有p = new(p) T{};
,则该代码具有明确定义的行为,假设没有自定义(DE(分配函数在播放中。(可以很容易地对付此类事情;这样做是作为读者的练习。(
规则是,您必须给非阵列delete
一个指向由非阵列new
创建的对象(或基类(带有虚拟破坏者(该对象的子对象或null指针(。随之而来的是您的代码做到这一点。
不需要非阵列 new
是非安置形式的。不可能,因为您最好能够删除new(std::nothrow) int
。这也是一个放置 new-expression ,即使人们通常并不意味着当他们谈论"安置新"时。
delete
定义为导致呼叫deallocation函数(忽略省略案例,这在这里是无关紧要的,因为 new> new-expression 所调用的唯一分配函数不是可更换的全局分配功能(。如果您设置了这些内容,以便将无效的参数传递给该交易函数,那么您就会从中获得不确定的行为。但是这里通过正确的地址(如果使用大小的DealLocation函数,则可以通过正确的大小(,因此定义明确。
我没有完全掌握OP的最后一段。明确称击曲和然后处理指针的乏味是什么?这就是我所见过的任何stl和任何有信誉的自由。是的,您必须跟踪分配内存的方式,才能将其归纳。阅读std :: vector和/或std :: shared_ptr的API文档可以使一个正确的方法熟悉。如果您不熟悉explacit dtor呼叫的语法,则是一个简单的片段:
void * raw_ptr= my_alloc(sizeof(my_type),alignof(my_type));
if (!raw_ptr)
throw my_bad_alloc();
my_type* ptr {new(raw_ptr) my_type{init_params}};
raw_ptr=nullptr;
//...
ptr->~my_type();//hello! Is it me you're lookin' for?
if (!my_dealloc(ptr))
throw my_runtime_error();
ptr=nullptr;
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 删除未使用新表达式构建的对象实际上可以吗?
- static_cast实际上不是对象类型的类型是未定义的行为吗?
- C 使用与自定义类对象的列表容器,列表:: Sort函数实际上并未对我的数据进行排序
- 我实际上是在调用 ctor 并在指向对象的指针上初始化 vtable 吗?C++
- 为什么复制构造函数被调用,即使我实际上正在复制到 C++ 中已经创建的对象
- 我实际上是否将对象存储在这里的 cpu 寄存器中