繁体   English   中英

std :: vector中元素的字节对齐是什么 <char> ?

[英]What is the byte alignment of the elements in a std::vector<char>?

我希望元素是1字节对齐的,类似地, std::vector<int>是4字节对齐的(或者特定平台上的任何大小的int )。

有谁知道标准库容器如何对齐?

在该实现中,容器的元素至少具有它们所需的对齐:如果int在您的实现中是4对齐的,那么vector<int>每个元素都是int ,因此是4对齐的。 我说“if”因为大小和对齐要求之间存在差异 - 只是因为int大小4并不一定意味着它必须是4对齐的,就标准而言。 但是,这很常见,因为int通常是机器的字大小,并且大多数机器都具有字边界内存访问的优势。 因此,即使它不是绝对必要的,也可以对齐int 例如,在x86上,您可以执行未对齐的字大小的内存访问,但它比对齐慢。 在ARM上,不允许使用未对齐的字操作,并且通常会崩溃。

vector保证连续存储,因此在vector<char>的第一个和第二个元素之间不会有任何“填充”,如果这是你所关心的。 std::vector的具体要求是0 < n < vec.size()&vec[n] == &vec[0] + n

[编辑:此位现在无关紧要,提问者已消除歧义:无论value_type是什么,容器本身通常都会有指针所需的对齐方式。 这是因为向量本身通常不会包含任何元素,但是会有一个指针指向一些动态分配的内存以及其中的元素。 这不是明确要求的,但它是一个可预测的实现细节。]

C ++中的每个对象都是1对齐的,唯一没有的是bitfields,而borderline-crazy特殊情况的元素是vector<bool> 所以你可以放心,你对std::vector<char>希望是有根据的。 向量及其第一个元素也可能是4对齐的;-)

至于它们如何对齐 - 就像C ++中的任何内容一致。 从堆中分配内存时,需要对任何适合分配的对象进行充分对齐。 当对象放在堆栈上时,编译器负责设计堆栈布局。 调用约定将指定堆栈指针在函数入口上的对齐,然后编译器知道它放下的每个对象的大小和对齐要求,因此它知道堆栈是否需要任何填充以使下一个对象进入正确的对齐。

我希望这些元素是1字节对齐的,并且类似于std :: vector是4字节对齐的(或者任何大小的int恰好在特定平台上)。

简单地说, std::vector是C数组的包装器。 向量的元素对齐就好像它们在数组中一样:元素保证占用连续的内存块而没有任何添加的间隙/ etc,因此std::vector<N> v可以使用&v[0]作为C数组访问&v[0] (为什么vector有时会在添加元素时重新分配存储空间。)

有谁知道标准库容器如何对齐?

元素的对齐是特定于平台的,但通常对齐一个简单的变量,使其地址可以被其大小(自然对齐)整除。 结构/等在它们包含的最大数据类型上填充(末端的空填充空间),以确保如果将结构放入数组中,则所有字段将保持其自然对齐。

对于其他容器(如std::liststd::map ),通过模板机制使用数据成为内部结构的一部分,结构由operator new分配。 new保证(自定义实现也必须遵守规则;继承自malloc() )以返回在最大可用原始数据类型(*)上对齐的内存块。 这是为了确保无论内存块中的哪个结构或变量都是位置,它将以对齐的方式访问。 std::vector不同,显然,大多数其他STL容器的元素不能保证在同一个连续内存块中:它们是逐个new编辑的,而不是new[]

(*)根据C ++标准,“new-expression(expr.new)调用的分配函数(basic.stc.dynamic.allocation)分配大小的存储字节,适当地对齐以表示该大小的任何对象。” 与一个malloc()通常相比,这是一个更软的要求,根据POSIX:“如果分配成功,返回的指针应该适当地对齐,以便它可以被分配给指向任何类型对象的指针[...]” 。 C ++需求在某种程度上重新满足了自然对齐要求:动态分配的char将按char需要对齐,但不能更多。

你的意思是矢量成员,还是矢量结构本身? 保证成员在内存中是连续的,但结构对齐依赖于平台/编译器。 在Windows上,这可以在编译时设置,也可以使用#pragma pack()覆盖。

其他容器的答案可能与vector不同,所以我会询问有关你关注的容器的具体问题。

整个容器的对齐取决于实现。 它通常至少是sizeof(void *),取决于平台,为4或8个字节,但可能更大。

如果需要特殊(保证)对齐,请使用普通数组或使用以下方法编写/调整某些通用数组类:

// allocation
char* pointer = _mm_malloc(size, alignment);
// deallocation
_mm_free(pointer);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM