UB是否在不破坏对象的情况下重新使用对象的存储? [英] Is it UB to re-use an object's storage without destroying it first?

查看:106
本文介绍了UB是否在不破坏对象的情况下重新使用对象的存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出非POD类型的T:

auto p = new T();
::new (p) T();
/* ... */
delete p;

这是UB,对吧?

很明显,我并没有直接泄漏为第一个T分配的内存(如果它没有间接成员,那么我就不会泄漏任何东西),但是它从未被破坏,在我看来一个自发灭绝由有感觉的猫状生物组成的星系的理想人选.

Clearly I'm not directly leaking the memory allocated for that first T (and if it has no indirect members then I'm not leaking anything at all), but it never got destructed, which seems to me to be a great candidate for spontaneous annihilation of galaxies populated by sentient cat-like beings.

感谢 @Xeo ,以便启发" C ++休息室中的这个问题.

Thanks to @Xeo for, um, "inspiring" this question in the C++ Lounge.

推荐答案

它取决于.

[C++11: 3.8/1]: 类型为T的对象的生存期在以下时间结束:

[C++11: 3.8/1]: The lifetime of an object of type T ends when:

  • 如果T是具有非平凡析构函数(12.4)的类类型,则将开始析构函数调用,或者
  • 对象占用的存储空间被重用或释放.
  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
  • the storage which the object occupies is reused or released.

很明显,这是重复使用的情况.

Clearly, this is a case of re-use.

并且:

[C++11: 3.8/4]: 程序可以通过重用对象占用的存储空间来结束任何对象的生存期,或通过为具有非平凡析构函数的类类型的对象显式调用析构函数来结束该对象的生命周期. 对于具有非平凡析构函数的类类型的对象,在重用或释放该对象占用的存储空间之前,不需要程序明确调用析构函数但是,如果没有显式调用析构函数,或者如果没有使用 delete-expression (5.3.5)释放存储,则不得隐式调用析构函数,并且不得使用任何程序取决于析构函数产生的副作用是否具有不确定的行为.

[C++11: 3.8/4]: A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

因此,即使对于非POD类型的T,它也是有效的 iff ,程序中的任何内容实际上都不依赖于析构函数的作用.

So, even for a non-POD type T, it's valid iff nothing in your program actually relied on what the destructor was doing.

这有点冒昧,但它确实可能允许您在做什么.

It's a bit airy-fairy, but it does potentially allow what you're doing.

请注意,这种宽大处理不会()扩展到一些更奇怪的情况:

Note that this leniency does not extend to some only slightly more bizarre cases:

[C++11: 3.8/9]:在具有静态,线程或自动存储持续时间的const对象所占据的存储位置处,或者在这样的const对象在其生命周期结束之前曾经占据的存储位置处,创建一个新对象会导致未定义行为

[C++11: 3.8/9]: Creating a new object at the storage location that a const object with static, thread, or automatic storage duration occupies or, at the storage location that such a const object used to occupy before its lifetime ended results in undefined behavior

这篇关于UB是否在不破坏对象的情况下重新使用对象的存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆