5

The following program on running with g++ 4.8.2 gave the output 12 on a 32-bit Linux system:

vector<char> v;
cout << sizeof(v) << endl;

I saw this and know that sizeof(v) could be implementation specific. Still, I was wondering what might be causing that vector to have a size of 12. What I think is that the iterators v.begin() and v.end() might be contributing to 8 bytes of the size. Am I correct? If yes, what is contributing to the remaining 4 bytes of size? If not, what are these 12 bytes all about?

Community
  • 1
  • 1
crisron
  • 363
  • 2
  • 5
  • 21
  • 1
    Related: http://stackoverflow.com/questions/26021339/c-understanding-size-t-behaviour-for-vector-creation – M.M Jan 14 '15 at 05:35
  • On my system it is 32 bytes (begin, size, capacity, allocator, plus four values related to iterator range checking) – M.M Jan 14 '15 at 05:37
  • @MattMcNabb : Would you please elaborate? – crisron Jan 14 '15 at 10:50
  • that's about all I know.. I haven't figured out exactly what it does with the iterator debugging fields, but it seems to keep track of all valid iterators into this vector so that it can detect if one has become invalidated. – M.M Jan 14 '15 at 20:10

3 Answers3

13

Take a look at the sources. libstdc++ is part of the gcc download.

Anyway, the container must have these members:

  1. A data-pointer, 4 bytes for a char*.
  2. An element count or an end pointer, 4 bytes for a size_t or char*.
  3. A buffer-size or pointer to end-of-buffer, 4 bytes for a size_t or char*.
  4. The standard allocator (empty trivial type) needs no space, thanks to some implementation-tricks (Empty-baseclass-optimization, and perhaps partial template-specialization. C++20 could use the attribute [[no_unique_address]] instead).

In theory, 2 and 3 might be smaller if not pointers. Though that would be curious, as it would restrict the maximum size.

Also in theory, 2 and 3 could be allocated dynamically with the data. Haven't found anyone actually do that though.

Together 12 bytes, as expected.
Double the sizes for a 64-bit implementation.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
5

Typically std::vector has:

1. Start of allocation / begin
2. End of vector (begin + size)
3. End of allocation (begin + capacity)

So size 12 is quite justified on a 32 bit machine.

Gyapti Jain
  • 4,056
  • 20
  • 40
3

libstdc++'s std::vector derived from a base with a data member of this type:

  struct _Vector_impl
  : public _Tp_alloc_type
  {
    pointer _M_start;
    pointer _M_finish;
    pointer _M_end_of_storage;
    ...

_M_end_of_storage supports .capacity() / resizing etc..

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252