In order to understand the memory consumption of std::vector<int>
I wrote:
std::cout << sizeof(std::vector<int>) << std::endl;
This yields 32
. I tried to understand where this value comes from. Some look in the source code revieled that std::vector
stores pointers _MyFirst
, _MyLast
and _MyEnd
which explaines 24 bytes of memory consumption (on my 64 bit system).
What about the last 8
byte? As I understand, the stored allocator does not use any memory. Also this might be implementation defined (is it?), so maybe this helps: I am working with MSVC 2017.5. I do not guarantee to have found all the members by looking into the code; the code looks very obfuscated to me.
Everything seems to be nicely aligned, but may the answer be the following?: Why isn't sizeof for a struct equal to the sum of sizeof of each member?. But I tested it with a simple struct Test { int *a, *b, *c; };
which satisfiessizeof(Test) == 24
.
Some background
In my program, I will have a lot of vectors and it seems that most of them will be empty. This means that the ciritical memory consumption comes from there empty-state, i.e. the heap allocated memory is not so very important.
A simple "just for this usecase"-vector is implemented pretty quickly, so I wondered if I am missing anything and I will need 32 bytes of memory anyway, even with my own implementation (note: I will most probably not implement my own, this is just curiosity).
Update
I tested it again with the following struct:
struct Test
{
int *a, *b, *c;
std::allocator<int> alloc;
};
which now gave sizeof(Test) == 32
. It seems that even though std::allocator
has no memory consuming members (I think), its presence raises Test
's size to 32 byte.
I recognized that sizeof(std::allocator<int>)
yields 1
, but I thought this is how a compiler deals with empty structs and that this is optimized away when it is used as a member. But this seems to be a problem with my compiler.
<vector>
headers (and the internal headers included from it)? Do you really care? Are you willing to spend weeks of work to understand all the gory details? On my Linux/GCC system,#include <vector>
expands to more than ten thousand lines of C++, and I did not took time to read all of them. BTW, most of the memory used by your vector is some data in the heap... – Peggiestd::vector
in a memory critical environment and I wondered "if I would implement it myself, would I be able to do any better?". I will most probably not implement anything myself, so mostly curiosity. I know about that most memory is on the heap. The problem is that it seems that I have a lot vectors, and most of them will be empty. So the empty-memory consumption is the important number here. – Printablevector
at all. It can pretty much be summed in, "on a 64 bit system, why doesstruct {void *_1; void *_2; void *_3; };
take up 32 bytes instead of 24?". If these are indeed the only member in the structure as you say. – Nadean<vector>
is coded by the same guys coding your compiler.... and they might improve that compiler to optimize it better. – Peggievector
can actually be implemented in an hour or so. It won't have all the stl functionality, like different kinds of iterators, tons of assignment variants and etc., but it will have what is necessary, and have the needed memory layout. – Abroad#include <vector>
expands to more than 10KLOC). In particular, because most compilers have some optimization passes related to their particular implementation of<vector>
. BTW, bravo if you can code the 10KLOC lines of<vector>
in one hour. Please teach me your tricks. I need several months of work to code good, debugged, documented, tested, optimized 10KLOC – Peggiesizeof(std::vector<int>)
is 24. So you might consider changing your compiler! – Peggievector
functionality that exists in STL. But specific subset of it can be implemented easily, and it will be suited for the needs. In particular in a described situation, where memory size of an emptyvector
is important - this is the way to go. – Abroadsizeof(vector)
, and for the empty case, you can do better. Much better. The idea would be that your customvector
will only contain a pointer. If the vector is empty, then it will benullptr
. If not, then this pointer will point to a memory, for which size/capacity/vector_contents stored. – Arbiter