c++ - 转换.c++后在char类型的原始缓冲区上调用delete

标签 c++ memory dynamic

在这个答案中:
https://stackoverflow.com/a/222578/4416169
使用此代码:

char *buf  = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi");    // placement new
string *q = new string("hi");          // ordinary heap allocation
有一条评论说:
请记住,在删除缓冲区之前手动销毁字符串,这就是下面的评论已经假设的内容。

Strictly, it's undefined behaviour to call delete[] on the original char buffer. Using placement new has ended the lifetime of the original char objects by re-using their storage. If you now call delete[] buf the dynamic type of the object(s) pointed to no longer matches their static type so you have undefined behaviour. It is more consistent to use operator new/operator delete to allocate raw memory inteded for use by placement new.


此评论对其声称的内容是否正确?我们是否应该创建一个 void* 指针缓冲区,使用运算符 new 创建它并使用运算符 delete 删除它,如下面的代码所示?:
void *raw_memory = operator new(sizeof(int));
int *dynamicInt = new(raw_memory) int;
operator delete(raw_memory);
这段代码^^严格等同于以下代码吗?:
void *raw_memory = operator new[](sizeof(int));//notice the [] after new
int *dynamicInt = new(raw_memory) int;
operator delete[](raw_memory);//notice the [] after delete
还是可以简单地使用 char* 缓冲区并执行通常的数组删除和新建?

最佳答案

Calling delete on original buffer of char type after casting .c++


请注意,示例中不涉及强制转换。

Using placement new has ended the lifetime of the original char objects by re-using their storage.



这当然是正确的。标准报价:

[basic.life] ... The lifetime of an object o ... ends when: ... the storage which the object occupies is ... reused by an object that is not nested within o



If you now call delete[] buf the dynamic type of the object(s) pointed to no longer matches their static type so you have undefined behaviour.



违规规则大概是这样的:

[expr.delete] In a single-object delete expression, if the static type of the object to be deleted is different from its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In an array delete expression, if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.


让我们来看看“动态类型”是什么意思:

[defns.dynamic.type] type of the most derived object ([intro.object]) to which the glvalue refers


[intro.object] If a complete object, a data member, or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject; an object of a most derived class type or of a non-class type is called a most derived object.


所以,这里的问题是没有对象,因此没有最派生的对象的类型可以与静态类型匹配。
对我来说,这似乎有点技术性,因为我们正在考虑一个微不足道的非类类型。对于裸操作符 new 来说,这种技术性不是问题。

Should we instead create a buffer of void* pointers with operator new


更好的是,我们可能应该使用 std::allocator<std::string>::allocate内部调用 ::operator new .这使得我们的程序更容易适应自定义分配器,并且不需要根据元素的大小来计算数组的大小。

关于c++ - 转换.c++后在char类型的原始缓冲区上调用delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62939015/

相关文章:

c - dlsym - "Too many arguments to function"错误

asp.net - 动态向 'GridView' 添加超链接列(服务器端)

c++ - LuaBridge getGlobal 总是返回 nil

c++ - 诺基亚 lumia 1020 USB 大容量存储访问 C++

C malloc 和自由函数的奇怪行为

c++ - 混合模式 c++/CLR 应用程序中内存使用过多

c++ - 引用变量是否占用内存?

c++ - C++文件的时间戳

c - 堆管理器的空闲列表存储在进程的地址空间中的什么位置?

c++ - 无法通过单击程序来运行程序,而我可以从终端运行程序