如何解释sizeof(std::vector<int>)的值?

How to explain the value of sizeof(std::vector<int>)?

本文关键字:int 何解释 gt 的值 lt 解释 sizeof std vector      更新时间:2023-10-16

为了了解我写的std::vector<int>的内存消耗:

std::cout << sizeof(std::vector<int>) << std::endl;

这产生32。我试图了解这个值的来源。有些查看源代码的查看std::vector存储Pointers _MyFirst_MyLast_MyEnd,该指针解释了24个字节内存消耗的字节(在我的64位系统上)。

最后一个8字节呢?据我了解,存储的分配器不使用任何内存。另外,这可能是定义的(是吗?),所以也许这会有所帮助:我正在使用MSVC 2017.5。我不保证通过查看代码找到所有成员;该代码看起来非常迷惑于我。

一切似乎都很好地对齐,但是答案可以是以下内容?但是我用满足sizeof(Test) == 24的简单struct Test { int *a, *b, *c; };进行了测试。


一些背景

在我的程序中,我将拥有很多向量的,似乎大多数将是空的。这意味着,官方记忆消耗来自那里的空国家,即分配的堆内存并不是那么重要。

一个简单的"仅适用于此用户" - 向量很快就实现了,所以我想知道我是否缺少任何东西,即使我自己的实现,我还是需要32个字节的内存( note> note :我很可能不会实现我自己的,这只是好奇心)。


update

我再次使用以下结构进行了测试:

struct Test
{
    int *a, *b, *c;
    std::allocator<int> alloc;
};

现在给出了sizeof(Test) == 32。似乎即使std::allocator没有内存消耗成员(我认为),它的存在将Test的大小提高到32字节。

我认识到sizeof(std::allocator<int>)产生了1,但我认为这是编译器处理空结构的方式,并且当将其用作成员时将其优化。但这似乎是我的编译器的问题。

编译器无法优化空成员。标准明确禁止它。

空类型的完整对象和成员子对象应具有非零大小

另一方面,一个空基类 subobject的大小可能为零。这正是GCC/libstdc 应对问题的方式:它使矢量实现继承了分配器。

std::vector的数据成员没有明显的信息,因此您可以假设其实现已定义。

您提到了三个指针,因此您可以以三个指针作为数据成员检查类(或结构)的大小。

我尝试运行此操作:

std::cout << sizeof(classWith3PtrsOnly) << " " << sizeof(std::vector<int>) << std::endl;

在wandbox上,得到:

24 24

几乎意味着额外的8个字节来自"添加填充以满足对齐约束"。

如果您在调试级别上使用Windows进行了上述测试,请注意"向量"。实现从" _vector_val"继承它在其_container_base类中有一个其他指针成员(除了我的first,mylast,myend):

_container_proxy* _myproxy

它仅在debug build中将矢量类的大小从24个字节增加到32个字节(其中_iterator_debug_level == 2)

我最近发生了同样的问题。尽管我仍然不知道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);