可以使用realloc安全地重新分配琐碎可复制对象的存储吗? [英] Can the storage of trivially copyable objects be safely reallocated with realloc?

查看:158
本文介绍了可以使用realloc安全地重新分配琐碎可复制对象的存储吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以轻松复制的对象可以安全地复制到我的放入适当的存储位置 1 ,目标对象将具有与源相同的值.

I know that trivially copyable objects can safely be copied my malloc into an appropriate storage location1 and that the destination object will have the same value as the source.

realloc也可以吗?也就是说,如果realloc某些包含某些类型为T的对象的存储,并且realloc决定移动并复制该块,则新分配的存储中的对象将保持不变并已开始其生存期,并且生存期将旧存储中的对象是否可以安全终止?

Is this also possible with realloc? That is, if realloc some storage containing some objects of type T, and realloc decides to move and copy the block, will the objects in the newly allocated storage be intact and have started their lifetime, and will the lifetime of the objects in the old storage be safely ended?

1 在问这个问题时,我曾假设适当的存储位置"包括未对齐的适当对齐方式和大小的存储,但以

1 While asking this question, I had assumed that an "appropriate storage location" included uninitialized storage of suitable alignment and size, but as M.M's answer below argues this isn't actually well supported by the standard. That would make realloc questionable since it is always copying into uninitialized storage.

推荐答案

,由于realloc无法创建新对象,因此realloc无法安全地移动对象,即使是可复制类型的对象也是如此.未初始化存储中的对象.

No, realloc cannot be used to safely move objects, even of trivially copyable types, because realloc cannot create new objects in uninitialized storage.

尤其是根据C ++ 14 [basic.life]/1:

In particular, according to C++14 [basic.life]/1:

类型为T的对象的生存期在以下情况下终止:

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.

调用realloc会释放或重新使用存储(即使您没有提出重新分配的请求,我也主张这样做,尽管这对于您的问题没有什么意义).这样,对象的生命周期就结束了.

Calling realloc releases or reuses the storage (even if a reallocation doesn't occur, I'd argue, although that is moot for your question). So the lifetime of the objects ends.

[intro.objects]/1涵盖了创建对象的情况:

The cases when an object is created is covered by [intro.objects]/1:

对象由定义(3.1),新表达式(5.3.4)创建 或在需要时通过实施(12.2).

An object is created by a definition (3.1), by a new-expression (5.3.4) or by the implementation (12.2) when needed.

这不包括realloc;因此realloc调用将结束旧对象的生命周期,并且不会创建新对象.

This does not include realloc; so the realloc call ends the lifetime of the old objects and does not create new objects.

这不仅意味着realloc不适合复制琐碎的可复制对象,还意味着使用mallocoperator new(size_t)获取未初始化的存储,然后使用memcpy从现有对象复制到该存储不会创建该对象的可用副本,因为在这种情况下也没有创建.

Not only does this imply that realloc isn't suitable to copy trivially copyable objects, it also implies that using malloc or operator new(size_t) to obtain uninitialized storage, followed by a memcpy from an existing object into that storage does not create a usable copy of the object as the destination object has also not been created in that case.

另请参见: reinterpret_cast创建普通可构造的对象,或

See also: reinterpret_cast creating a trivially-default-constructible object, or constructing a trivially copyable object with memcpy for further discussion of the fact that copying bytes to a new location does not create an object in that location.

这篇关于可以使用realloc安全地重新分配琐碎可复制对象的存储吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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