是否可以在放置新分配的对象上不调用析构函数? [英] Is it OK not to call the destructor on placement new allocated objects?

查看:60
本文介绍了是否可以在放置新分配的对象上不调用析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个固定的内存缓冲区

Say I have a fixed memory buffer

char *buffer; 

然后,我使用新的展示位置在该缓冲区中分配我的结构

struct S
{ 
    std::tuple<int, double, char> m_data; 
    auto getRecord() 
    { 
        return m_data;
    }
};

S *newS = new(buffer + offset)S; 

我知道应该手动调用此类已分配项目的析构函数,但如果不涉及布管/资源管理,可以忽略吗?换句话说,如果使用缓冲区的类的析构函数没有做任何事情(类似于上面的〜S()),可以跳过此步骤吗?如果是这种情况,我可以在不破坏先前租户的情况下重用缓冲区吗?

I know that I'm supposed to manually call the destructor of such allocated items but if there's no bookeeping / resource management involved is it ok to omit this? In other words if the destructor of the classes using the buffer is not doing anything (similar to ~S() above) is it ok to skip this step? If that's the case can I reuse the buffer without destroying the previous tenants?

推荐答案

该标准在第3.8节 [basic.life] 中有一条适用于此的规则:

The standard has a rule in section 3.8 [basic.life] that covers this:

程序可以通过重用该对象占用的存储空间或通过为具有非平凡析构函数的类类型的对象显式调用析构函数来结束任何对象的生命周期.对于具有非平凡析构函数的类类型的对象,不需要程序在重用或释放该对象占用的存储空间之前显式调用析构函数;但是,如果没有显式调用析构函数,或者没有使用delete-expression(5.3.5)释放存储,则不应隐式调用析构函数,并且任何依赖于产生副作用的程序破坏者具有未定义的行为.

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.

许多专家都同意取决于破坏者产生的副作用".太含糊而无法使用.许多人将其解释为重言式,意思是如果在未评估析构函数的副作用时程序具有未定义的行为,则未能调用析构函数会导致未定义的行为".请参见可观察到的行为和未定义的行为-如果我不调用析构函数会发生什么?

Lots of experts are in agreement that "depends on the side effects produced by the destructor" is far too vague to be useful. Many interpret it as a tautology meaning "If the program has undefined behavior when the destructor side effects are not evaluated, then failing to call the destructor causes undefined behavior". See Observable behavior and undefined behavior -- What happens if I don't call a destructor?

如果您的类型具有琐碎的析构函数(在您的示例中似乎是这种情况),则调用它(或未能调用它)根本没有效果-呼叫琐碎的析构函数甚至都不会终止该方法的寿命.对象.

If your type has a trivial destructor (which appears to be the case in your example), then calling it (or failing to call it) has no effect whatsoever -- calling a trivial destructor does not even end the life of the object.

类型为 T 的对象 o 的生​​存期在以下时间结束:

The lifetime of an object o of type T ends when:

  • 如果 T 是具有非平凡析构函数的类类型,则析构函数调用将开始,或者
  • 对象占用的存储已释放,或被未嵌套在 o 中的对象重用.
  • if T is a class type with a non-trivial destructor, the destructor call starts, or
  • the storage which the object occupies is released, or is reused by an object that is not nested within o.

也就是说,如果 T 没有简单的析构函数,则结束对象 o 的生​​存期的唯一方法是释放或重新使用其存储.

That is, if T doesn't have a non-trivial destructor, the only way to end the lifetime of object o is to release or reuse its storage.

这篇关于是否可以在放置新分配的对象上不调用析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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