char数组的对齐方式

时间:2010-10-24 17:30:59

标签: c++ alignment

STL载体通常如何实施?它有一个char []的原始存储,它偶尔会按某个因子调整大小,然后在一个元素被push_back时调用placement new(我应该注意一个非常有趣的语法形式 - 语言学家应该像push_back一样学习这样的动词形式)。 > 然后是对齐要求。因此,一个自然的问题是如何在char []上调用new new,并确保满足对齐要求。所以我在2003年的C ++标准中搜索了“alignment”这个词并找到了这些:

第3.9段第5条

对象类型具有对齐要求(3.9.1,3.9.2)。完整对象类型的对齐是表示字节数的实现定义的整数值;对象在满足其对象类型的对齐要求的地址处分配。

第5.3.4段第10条:

new-expression将请求的空间量作为std :: size_t类型的第一个参数传递给分配函数。该参数不得小于正在创建的对象的大小;仅当对象是数组时,它可能大于正在创建的对象的大小。对于char和unsigned char的数组,new-expression的结果与分配函数返回的地址之间的差异应该是任何对象类型的最严格对齐要求(3.9)的整数倍,其大小不大于正在创建的数组的大小。 [注意:因为假定分配函数返回指向适合任何类型对象的存储的指针,所以对数组分配开销的这种约束允许分配字符数组的常用习惯用法,稍后将放置其他类型的对象。 ]

这两个对我上面的问题给出了完全满意的答案,但是......

语句1:
对于类型为X的对象的对齐要求,其中sizeof(X)== n至少要求X的地址可以被n或类似的东西整除(将所有依赖于体系结构的东西放入“或类似的东西”中) )。

问题1: 请确认,改进或拒绝上述声明1.

语句2:如果statement1是正确的,则从标准中的第二个引号开始,在5000000处可分割的地址分配5000000个字符的数组,如果我只需要char数组,则完全没有这个数组,而不是原始存储空间,用于放置其他对象。

问题2: 那么,成功分配1000个字符的机会是否真的低于500个短路(短路为2个字节)?这实际上是个问题吗?

3 个答案:

答案 0 :(得分:4)

使用operator new动态分配内存时,可以保证:

  

返回的指针应适当对齐,以便可以将其转换为任何完整对象类型的指针,然后用于访问分配的存储中的对象或数组(直到通过调用相应的方式显式释放存储空间)解除分配函数)(C ++ 03 3.7.3.1/2)。

vector不会创建char数组;它使用分配器。默认分配器使用::operator new来分配内存。

答案 1 :(得分:3)

  

对象的对齐要求   其中sizeof(X)== n的类型为X.   至少要求的地址   X可以被n或类似的东西整除   该

没有。类型的对齐要求始终是其大小的因素,但不必等于其大小。它通常等于一个类的所有成员的最大对齐要求。

一个5M char的数组,就其自身而言,只需要对齐要求为1,与单个char的对齐要求相同。

因此,您引用的关于通过全局运算符new分配的内存对齐的文本(和malloc具有类似的虽然IIRC不相同的要求)实际上意味着大量分配必须服从系统中任何类型的最严格的对齐要求。此外,实现通常从中排除大型SIMD类型,并且需要专门分配用于SIMD的存储器。这有点可疑,但我认为他们证明了这一点,因为非标准的扩展类型可以强加任意的特殊要求。

所以在实践中,你认为5000000的数字通常是4: - )

答案 2 :(得分:1)

Q1:对齐与大小无关。

第二季度:理论上是的,但你很难找到一个具有如此巨大排列的类型的架构。 SSE需要16字节对齐(我见过的最大)。