【发布时间】:2017-11-27 09:31:09
【问题描述】:
为了了解std::vector<int>的内存消耗我写了:
std::cout << sizeof(std::vector<int>) << std::endl;
这会产生32。我试图了解这个值的来源。有些人在源代码中看到std::vector存储指针_MyFirst、_MyLast和_MyEnd,这解释了24字节的内存消耗(在我的64位系统上)。
最后一个8 字节呢?据我了解,存储的分配器不使用任何内存。这也可能是实现定义的(是吗?),所以这可能会有所帮助:我正在使用 MSVC 2017.5。我不保证通过查看代码找到了所有成员;这段代码在我看来很模糊。
一切似乎都很好地对齐,但答案可能如下?:Why isn't sizeof for a struct equal to the sum of sizeof of each member?。但我用一个简单的struct Test { int *a, *b, *c; }; 对其进行了测试,它满足sizeof(Test) == 24。
一些背景
在我的程序中,我将有 很多 个向量,而且似乎大多数都是空的。这意味着关键的内存消耗来自空状态,即堆分配的内存不是那么重要。
一个简单的“仅用于这个用例”-vector 的实现速度非常快,所以我想知道我是否遗漏了什么,无论如何我都需要 32 字节的内存,即使是我自己的实现(note :我很可能不会实现我自己的,这只是好奇)。
更新
我用下面的结构再次测试了它:
struct Test
{
int *a, *b, *c;
std::allocator<int> alloc;
};
现在给了sizeof(Test) == 32。似乎即使std::allocator 没有消耗内存的成员(我认为),它的存在也将Test 的大小提高到了 32 字节。
我认识到sizeof(std::allocator<int>) 产生1,但我认为这是编译器处理空结构的方式,并且在将其用作成员时已对其进行了优化。但这似乎是我的编译器的问题。
【问题讨论】:
-
为什么要解释?您是否深入研究了
<vector>标头的源代码(以及其中包含的 internal 标头)?你真的在乎吗?你愿意花费数周的时间来了解所有血淋淋的细节吗?在我的 Linux/GCC 系统上,#include <vector>扩展到了一万多行 C++,我没有花时间阅读所有这些。顺便说一句,您的向量使用的大部分内存都是堆中的一些数据... -
@BasileStarynkevitch 部分好奇。聚会,因为我必须在内存关键环境中使用
std::vector,我想知道“如果我自己实现它,我能做得更好吗?”。我很可能不会自己实现任何东西,所以主要是好奇心。我知道大多数内存都在堆上。问题是我似乎有 很多 向量,其中大部分都是空的。所以空内存消耗是这里的重要数字。 -
您的问题似乎根本与
vector无关。它几乎可以概括为“在 64 位系统上,为什么struct {void *_1; void *_2; void *_3; };占用 32 个字节而不是 24 个字节?”。如果这些确实是您所说的结构中的唯一成员。 -
顺便说一句,在我的 Linux/GCC/x86-64/Debian/Sid
sizeof(std::vector<int>)上是 24。所以你可以考虑改变你的编译器! -
@BasileStarynkevitch:正如我所说,我并不是说要实现 STL 中存在的所有
vector功能。但是它的特定子集可以很容易地实现,并且适合需求。特别是在所描述的情况下,空vector的内存大小很重要 - 这是要走的路。
标签: c++ vector stl sizeof stdvector