可以使用 realloc 安全地重新分配普通可复制对象的存储吗?
Can the storage of trivially copyable objects be safely reallocated with realloc?
我知道 trivially copyable 对象可以安全地复制我的 malloc
到适当的存储位置1 并且目标对象将具有相同的值作为来源。
realloc
也可以这样吗?也就是说,如果 realloc
一些存储包含一些 T
类型的对象,并且 realloc
决定移动和复制该块,那么新分配的存储中的对象是否完好无损并开始了它们的工作?生命周期,旧存储中对象的生命周期是否会安全结束?
1 在问这个问题时,我曾假设 "appropriate storage location" 包含未初始化的适当对齐和大小的存储,但正如下面的 所论证的那样实际上并没有得到标准的很好支持。这会让 realloc
产生疑问,因为它总是复制到未初始化的存储中。
否,realloc
不能用于安全移动对象,即使是普通可复制类型,因为realloc
不能在未初始化的存储中创建新对象。
特别是,根据 C++14 [basic.life]/1:
The lifetime of an object of type T ends when:
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
释放或重用存储(即使没有发生重新分配,我认为,尽管这对您的问题没有实际意义)。所以对象的生命周期结束了。
创建对象的情况由[intro.objects]/1 涵盖:
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 调用结束了旧对象的生命周期并且不创建新对象。
这不仅意味着 realloc
不适合复制平凡可复制的对象,还意味着使用 malloc
或 operator new(size_t)
来获取未初始化的存储,然后是memcpy
从现有对象到该存储不会创建该对象的可用副本,因为在这种情况下目标对象也没有被 创建 。
另请参阅:, or 以进一步讨论将字节复制到新位置不会在该位置创建对象这一事实。
3.8对象生命周期明确:
The lifetime of an object of type T begins when:
1.1 storage with the proper alignment and size for type T is obtained, and
1.2 if the object has non-vacuous initialization, its initialization is complete.
生命周期结束时也是如此。你可以忽略 std 其他部分的垃圾,比如 [intro]!
我知道 trivially copyable 对象可以安全地复制我的 malloc
到适当的存储位置1 并且目标对象将具有相同的值作为来源。
realloc
也可以这样吗?也就是说,如果 realloc
一些存储包含一些 T
类型的对象,并且 realloc
决定移动和复制该块,那么新分配的存储中的对象是否完好无损并开始了它们的工作?生命周期,旧存储中对象的生命周期是否会安全结束?
1 在问这个问题时,我曾假设 "appropriate storage location" 包含未初始化的适当对齐和大小的存储,但正如下面的 realloc
产生疑问,因为它总是复制到未初始化的存储中。
否,realloc
不能用于安全移动对象,即使是普通可复制类型,因为realloc
不能在未初始化的存储中创建新对象。
特别是,根据 C++14 [basic.life]/1:
The lifetime of an object of type T ends when:
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
释放或重用存储(即使没有发生重新分配,我认为,尽管这对您的问题没有实际意义)。所以对象的生命周期结束了。
创建对象的情况由[intro.objects]/1 涵盖:
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 调用结束了旧对象的生命周期并且不创建新对象。
这不仅意味着 realloc
不适合复制平凡可复制的对象,还意味着使用 malloc
或 operator new(size_t)
来获取未初始化的存储,然后是memcpy
从现有对象到该存储不会创建该对象的可用副本,因为在这种情况下目标对象也没有被 创建 。
另请参阅:
3.8对象生命周期明确:
The lifetime of an object of type T begins when:
1.1 storage with the proper alignment and size for type T is obtained, and
1.2 if the object has non-vacuous initialization, its initialization is complete.
生命周期结束时也是如此。你可以忽略 std 其他部分的垃圾,比如 [intro]!