![](/img/trans.png)
[英]Find a value of an element in vector in a std::map < int , std::vector <int >>
[英]How to explain the value of sizeof(std::vector<int>)?
為了了解std::vector<int>
的內存消耗,我寫道:
std::cout << sizeof(std::vector<int>) << std::endl;
這產生32
。 我試圖了解這個價值從何而來。 一些查看源代碼的人認為std::vector
存儲指針_MyFirst
、 _MyLast
和_MyEnd
,這解釋了 24 字節的內存消耗(在我的 64 位系統上)。
最后8
個字節呢? 據我了解,存儲的分配器不使用任何內存。 這也可能是實現定義的(是嗎?),所以這可能會有所幫助:我正在使用 MSVC 2017.5。 我不保證通過查看代碼找到所有成員; 代碼對我來說看起來很模糊。
一切似乎都很好地對齊,但答案可能如下?:為什么結構的 sizeof 不等於每個成員的 sizeof 之和? . 但是我用一個簡單的struct Test { int *a, *b, *c; };
對其進行了struct Test { int *a, *b, *c; };
struct Test { int *a, *b, *c; };
滿足sizeof(Test) == 24
。
一些背景
在我的程序中,我將有很多向量,而且它們中的大部分似乎都是空的。 這意味着重要的內存消耗來自空狀態,即堆分配的內存不是那么重要。
一個簡單的“僅用於此用例”-vector 實現得非常快,所以我想知道我是否遺漏了什么,無論如何我都需要 32 字節的內存,即使是我自己的實現(注意:我很可能不會實現我自己的,這只是好奇)。
更新
我用以下結構再次測試了它:
struct Test
{
int *a, *b, *c;
std::allocator<int> alloc;
};
現在給出了sizeof(Test) == 32
。 似乎即使std::allocator
沒有消耗內存的成員(我認為),但它的存在將Test
的大小提高到 32 字節。
我認識到sizeof(std::allocator<int>)
產生1
,但我認為這是編譯器處理空結構的方式,並且當它用作成員時會被優化掉。 但這似乎是我的編譯器的問題。
std::vector
的數據成員沒有標准化,因此您可以假設它是實現定義的。
您提到了三個指針,因此您可以使用三個指針作為其數據成員來檢查類(或結構)的大小。
我試過運行這個:
std::cout << sizeof(classWith3PtrsOnly) << " " << sizeof(std::vector<int>) << std::endl;
在Wandbox 上,得到:
24 24
這幾乎意味着額外的 8 個字節來自“為滿足對齊約束而添加的填充”。
編譯器無法優化掉一個空成員。 這是標准明確禁止的。
空類類型的完整對象和成員子對象應具有非零大小
另一方面,空基類子對象的大小可能為零。 這正是 GCC/libstdc++ 處理問題的方式:它使向量實現繼承了分配器。
我最近發生了同樣的問題。 雖然我仍然不知道std::vector
是如何進行這種優化的,但我發現了一種通過 C++20 的方法。
C++ 屬性:no_unique_address (C++20 起)
struct Empty {};
struct NonEmpty {
int* p;
};
template<typename MayEmpty>
struct Test {
int* a;
[[no_unique_address]] MayEmpty mayEmpty;
};
static_assert(sizeof(Empty) == 1);
static_assert(sizeof(NonEmpty) == 8);
static_assert(sizeof(Test<Empty>) == 8);
static_assert(sizeof(Test<NonEmpty>) == 16);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.