簡體   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