std::vector中元素的字节对齐方式是什么?

发布于 2024-09-18 13:12:48 字数 117 浏览 3 评论 0原文

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

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

I'm hoping that the elements are 1 byte aligned and similarly that a std::vector<int> is 4 byte aligned ( or whatever size int happens to be on a particular platform ).

Does anyone know how standard library containers get aligned?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笙痞 2024-09-25 13:12:48

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

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

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

C++ 中的每个对象都是 1 对齐的,唯一不是位域,以及边界疯狂特殊情况的元素,即 vector< ;布尔> 。所以你可以放心,你对 std::vector 的希望是有根据的。向量及其第一个元素也可能是 4 对齐的;-)

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

The elements of the container have at least the alignment required for them in that implementation: if int is 4-aligned in your implementation, then each element of a vector<int> is an int and therefore is 4-aligned. I say "if" because there's a difference between size and alignment requirements - just because int has size 4 doesn't necessarily mean that it must be 4-aligned, as far as the standard is concerned. It's very common, though, since int is usually the word size of the machine, and most machines have advantages for memory access on word boundaries. So it makes sense to align int even if it's not strictly necessary. On x86, for example, you can do unaligned word-sized memory access, but it's slower than aligned. On ARM unaligned word operations are not allowed, and typically crash.

vector guarantees contiguous storage, so there won't be any "padding" in between the first and second element of a vector<char>, if that's what you're concerned about. The specific requirement for std::vector is that for 0 < n < vec.size(), &vec[n] == &vec[0] + n.

[Edit: this bit is now irrelevant, the questioner has disambiguated: The container itself will usually have whatever alignment is required for a pointer, regardless of what the value_type is. That's because the vector itself would not normally incorporate any elements, but will have a pointer to some dynamically-allocated memory with the elements in that. This isn't explicitly required, but it's a predictable implementation detail.]

Every object in C++ is 1-aligned, the only things that aren't are bitfields, and the elements of the borderline-crazy special case that is vector<bool>. So you can rest assured that your hope for std::vector<char> is well-founded. Both the vector and its first element will probably also be 4-aligned ;-)

As for how they get aligned - the same way anything in C++ gets aligned. When memory is allocated from the heap, it is required to be aligned sufficiently for any object that can fit into the allocation. When objects are placed on the stack, the compiler is responsible for designing the stack layout. The calling convention will specify the alignment of the stack pointer on function entry, then the compiler knows the size and alignment requirement of each object it lays down, so it knows whether the stack needs any padding to bring the next object to the correct alignment.

む无字情书 2024-09-25 13:12:48

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

简而言之,std::vector 是 C 数组的包装器。向量的元素像在数组中一样对齐:保证元素占据连续的内存块,而不会添加任何间隙等,因此 std::vectorv 可以使用 &v[0] 作为 C 数组进行访问。 (为什么向量在添加元素时有时必须重新分配存储空间。)

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

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

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

(*) 根据 C++ 标准,“由 new 表达式 (expr.new) 调用的分配函数 (basic.stc.dynamic.allocation) 来分配 size 字节的存储,适当对齐以表示该大小的任何对象。”与通常遵守的 malloc() 相比,这是一个更软的要求,根据 POSIX:“分配成功时返回的指针应适当对齐,以便可以将其分配给指向任何类型的指针。目的 [...]”。 C++ 要求在某种程度上强化了自然对齐要求:动态分配的 char 将按照 char 的要求进行对齐,但不会更多。

I'm hoping that the elements are 1 byte aligned and similarly that a std::vector is 4 byte aligned ( or whatever size int happens to be on a particular platform ).

To put it simply, std::vector is a wrapper for a C array. The elements of the vector are aligned as if they were in the array: elements are guaranteed to occupy continues memory block without any added gaps/etc, so that std::vector<N> v can be accessed as a C array using the &v[0]. (Why vector has to reallocate storage sometimes when elements are added to it.)

Does anyone know how standard library containers get aligned?

Alignment of elements is platform specific but generally a simple variable is aligned so that its address is divisible by its size (natural alignment). Structures/etc are padded (empty filler space at the end) on the largest data type they contain to ensure that if the structure is put into an array, all fields would retain their natural alignment.

For other containers (like std::list or std::map) use data via template mechanics are made a part of internal structure and the structure is allocated by operator new. The new is guaranteed (custom implementation must obey the rule too; inherited from the malloc()) to return memory block which is aligned on largest available primitive data type (*). That is to ensure that regardless what structure or variable would be places in the memory block, it will be accessed in aligned fashion. Unlike std::vector, obviously, the elements of most other STL containers are not guaranteed to be within the same continuous memory block: they are newed one by one, not with new[].

(*) As per C++ standard, "The allocation function (basic.stc.dynamic.allocation) called by a new-expression (expr.new) to allocate size bytes of storage suitably aligned to represent any object of that size." That is a softer requirement compared to one malloc() generally abides, as per POSIX: "The pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object [...]". C++ requirement in a way reenforces the natural alignment requirement: dynamically allocated char would be aligned as char requires, but not more.

浴红衣 2024-09-25 13:12:48

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

其他容器的答案可能与向量不同,因此我会询问有关您关心的容器的具体问题。

Do you mean the vector members, or the vector structure itself? Members are guaranteed to be contiguous in memory but structure alignment is platform/compiler-dependent. On Windows this can be set at compile-time and also overridden using #pragma pack().

The answer for other containers is likely not the same as for vector, so I would ask specific questions about the ones you care about.

潇烟暮雨 2024-09-25 13:12:48

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

The alignment of the whole container is implementation dependent. It is usually at least sizeof(void*), that is 4 or 8 bytes depending on the platform, but may be larger.

ㄖ落Θ余辉 2024-09-25 13:12:48

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

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

If special (guaranteed) alignment is needed use plain arrays or write/adapt some generic array class with:

// allocation
char* pointer = _mm_malloc(size, alignment);
// deallocation
_mm_free(pointer);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文