刊登新刊 [英] Placement new issue
问题描述
在此我需要C ++数组类模板,该模板是固定大小的,基于堆栈的并且不需要默认构造函数答案我张贴了一段代码,即使用char数组新的位置。对我来说,这是绝对正常的事情。但是根据评论,此代码是错误的。
In this I need C++ array class template, which is fixed-size, stack-based and doesn't require default constructor answer I posted a piece of code, that is using placement new with char array. For me, this is something absolutely normal. But according to comments this code is wrong.
有人可以详细解释吗?
具体说怎么办数组错误。我从评论中了解到 T x [size];
可能不适合 char x [size * sizeof(T)];
。我不相信这是真的。
Specifically what can go wrong with the array. What I understand from the comments is that T x[size];
might not fit into char x[size*sizeof(T)];
. I don't believe this is true.
编辑:
我越来越困惑了。我知道结构的对齐方式。是的,当您拥有一个结构时,属性以不同的偏移量开始,那么您可能会想。
I'm just more and more confused. I know what alignment is in case of structures. Yes, when you have a structure the attributes start on different offsets then you might think.
好的,现在我们回到数组。您是在告诉我 T x [size];
与 char x [size * sizeof(T)];
,但是我可能无法将char数组作为T数组访问,因为可能会有一些对齐。数组大小相同时,如何对齐?
OK, now we are back to arrays. You are telling me that T x[size];
is the same size as char x[size*sizeof(T)];
, yet I cannot access the char array as T array because there might be some alignment. How can there be alignment when the arrays have the same size?
编辑2:
好,我终于明白了
编辑3:
谢谢大家,您可以停止发布:-) ew,这总让我大吃一惊。我只是从未意识到这是不可能的。
Thx everyone, you can stop posting :-) Phew, this total blew my mind. I just never realized this was possible.
推荐答案
A T x [size]
数组将始终完全适合 size * sizeof(T)
个字节,这意味着 char buffer [size * sizeof(T)]
总是足以存储这样的数组。
A T x[size]
array will always fit exactly into size * sizeof(T)
bytes, meaning that char buffer[size*sizeof(T)]
is always precisely enough to store such an array.
据我所知,该答案中的问题是您的 char
数组不能保证正确 aligned 用于存储 T
类型的对象。仅保证 malloc
-ed / new
-ed缓冲区可以正确对齐以存储较小或较小的任何标准数据类型大小相等(或由标准数据类型组成的数据类型),但如果仅显式声明 char
数组(作为本地对象或成员子对象),则无法保证。
The problem in that answer, as I understood it, was that your char
array is not guaranteed to be properly aligned for storing the object of type T
. Only malloc
-ed/new
-ed buffers are guaranteed to be aligned properly to store any standard data type of smaller or equal size (or data type composed of standard data types), but if you just explicitly declare a char
array (as a local object or member subobject), there's no such guarantee.
对齐意味着在某些平台上可能严格(或并非如此严格)要求分配所有 int
对象位于一个4字节的边界上。例如。您可以将 int
对象放在地址 0x1000
或 0x1004
,但不能在地址 0x1001
处放置 int
对象。或者,更准确地说,您可以,但是任何尝试以 int
类型的对象访问此内存位置的操作都会导致崩溃。
Alignment means that on some platform it might be strictly (or not so strictly) required to allocate, say, all int
objects on, say, a 4-byte boundary. E.g. you can place an int
object at the address 0x1000
or 0x1004
, but you cannot place an int
object at the address0x1001
. Or, more precisely, you can, but any attempts to access this memory location as an object of type int
will result in a crash.
创建任意 char
数组时,编译器不知道您打算将其用于什么。它可以决定将该数组放置在地址 0x1001
中。由于上述原因,天真地尝试在这种未对齐的缓冲区中创建 int
数组将失败。
When you create an arbitrary char
array, the compiler does not know what you are planning to use it for. It can decide to place that array at the address 0x1001
. For the above reason, a naive attempt to create an int
array in such an unaligned buffer will fail.
某些平台上的对齐要求非常严格,这意味着任何尝试使用未对齐数据的操作都将导致运行时失败。在其他一些平台上,它们的要求不那么严格:代码可以工作,但性能会受到影响。
The alignment requirements on some platform are strict, meaning that any attempts to work with misaligned data will result in run-time failure. On some other platforms they are less strict: the code will work, but the performance will suffer.
有时需要正确对齐,这意味着当您要在任意<$中创建 int
数组时c $ c> char 数组,您可能必须 shift 将 int
数组的开头从 char
数组。例如,如果 char
数组位于 0x1001
,则您别无选择,只能开始就地构建地址 0x1004
中的 int
数组(即 char
索引为3的元素。为了容纳移位后的 int
数组的尾部, char
数组必须比3个字节大。 size * sizeof(T)
的计算结果。这就是为什么原始大小可能不够的原因。
The need for the proper alignment sometimes means that when you want to create an int
array in an arbitrary char
array, you might have to shift the beginning of an int
array forward from the beginning of the char
array. For example, if the char
array resides at 0x1001
, you have no choice but to start your constructed-in-place int
array from the address 0x1004
(which is the char
element with the index 3). In order to accommodate the tail portion of the shifted int
array, the char
array would have to be 3 bytes larger than what the size * sizeof(T)
evaluates to. This is why the original size might not be enough.
通常,如果您的 char
数组未对齐这样,您实际上将需要一个 size * sizeof(T)+ A-1
字节的数组来容纳一个对齐的(即可能移位的)类型为<$ c的对象数组$ c> T 必须与A字节边界对齐。
Generally, if your char
array is not aligned in any way, you will really need an array of size * sizeof(T) + A - 1
bytes to accommodate an aligned (i.e. possibly shifted) array of objects of type T
that must be aligned at A-byte boundary.
这篇关于刊登新刊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!