在此I need C++ array class template, which is fixed-size, stack-based and doesn't require default constructor answer 我发布了一段代码,即使用 placement new 和 char 数组。对我来说,这是绝对正常的事情。但根据评论,这段代码是错误的。
谁能详细解释一下?
具体来说,数组可能会出现什么问题。我从评论中了解到 T x[size];
可能不适合 char x[size*sizeof(T)];
。我不相信这是真的。
编辑:
我只是越来越糊涂了。我知道在结构的情况下对齐是什么。是的,当你有一个结构时,属性开始于不同的偏移量,然后你可能会想。
好的,现在我们回到数组。您告诉我 T x[size];
与 char x[size*sizeof(T)];
的大小相同,但我无法访问 char 数组T 数组,因为可能会有一些对齐。大小相同的数组如何对齐?
编辑 2:
好的,我终于明白了,它可能从错误的地址开始。
编辑 3:
谢谢大家,你们可以停止发帖 :-) 呸,这让我大吃一惊。我只是从来没有意识到这是可能的。
最佳答案
T x[size]
数组将始终正好适合 size * sizeof(T)
字节,这意味着 char buffer[size*sizeof(T )]
总是足够精确地存储这样一个数组。
据我了解,该答案中的问题是您的 char
数组不能保证正确对齐以存储 T 类型的对象
。只有 malloc
-ed/new
-ed 缓冲区才能保证正确对齐以存储任何小于或等于大小的标准数据类型(或由标准数据类型组成的数据类型) ,但如果您只是显式声明一个 char
数组(作为本地对象或成员子对象),则没有这样的保证。
对齐意味着在某些平台上,可能严格(或不那么严格)要求在 4 字节边界上分配所有 int
对象。例如。您可以在地址 0x1000
或 0x1004
处放置一个 int
对象,但不能在地址处放置一个 int
对象地址0x1001
。或者,更准确地说,您可以,但是任何尝试将此内存位置作为 int
类型的对象进行访问都将导致崩溃。
当你创建一个任意的 char
数组时,编译器不知道你打算用它做什么。它可以决定将该数组放置在地址 0x1001
处。由于上述原因,在这种未对齐的缓冲区中创建 int
数组的天真尝试将失败。
某些平台上的对齐要求非常严格,这意味着任何尝试使用未对齐的数据都将导致运行时失败。在其他一些平台上,它们没有那么严格:代码可以运行,但性能会受到影响。
正确对齐的需要有时意味着当您想在任意 char
数组中创建一个 int
数组时,您可能必须 shift int
数组的开头,从 char
数组的开头向前。例如,如果 char
数组驻留在 0x1001
,您别无选择,只能从地址开始就地构造 int
数组0x1004
(这是索引为 3 的 char
元素)。为了容纳移位后的 int
数组的尾部,char
数组必须比 size * sizeof(T)
评估为。这就是原始尺寸可能不够用的原因。
通常,如果您的 char
数组没有以任何方式对齐,您确实需要一个 size * sizeof(T) + A - 1
字节的数组来容纳必须在 A 字节边界对齐的 T
类型对象的对齐(即可能移位)数组。
关于c++ - 安置新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3874615/