2

On my MS VS 2015 compiler, the sizeof int is 4 (bytes). But the sizeof vector<int> is 16. As far as I know, a vector is like an empty box when it's not initialized yet, so why is it 16? And why 16 and not another number?

Furthermore, if we have vector<int> v(25); and then initialize it with int numbers, then still the size of v is 16 although it has 25 int numbers! The size of each int is 4 so the sizeof v should then be 25*4 bytes seemingly but in effect, it is still 16! Why?

Franky
  • 1,181
  • 2
  • 11
  • 33
  • Can you check size of a `int *` variable? I think 16 is pointer size in your machine – niyasc Mar 15 '16 at 06:56
  • The `sizeof (int*)` is 4. – Franky Mar 15 '16 at 07:00
  • 3
    It is a fundamental C++ rule that the size of a type does not vary with its contents. For example: `char *j = "hello": char *k = "goodbye";`. Since `j` and `k` are both of type `char *`, they occupy the same number of bytes. The size of stuff that they can be used to access is not relevant. – David Schwartz Mar 15 '16 at 07:03
  • 1
    I suggest you to write your own 'vector' class for better understanding. Start with non-template, then templatize your vector class. You'll get solid understanding! – Ajay Mar 15 '16 at 07:05
  • @niyasc Implementing a `std::vector` requires at least 3 pointer-sized objects (or actually one pointer and two `std::size_t`-sized objects). On a 32-bit system, with a 4-byte pointer, and allowing for alignment, 16 is a reasonable size for a `std::vector`. – Angew is no longer proud of SO Mar 15 '16 at 07:31
  • @DavidSchwartz: Thanks for your comment. it was useful. Why didn't you offer an answer with more details including the context of that comment so? – Franky Mar 16 '16 at 10:30
  • @franky Generally, when I give a comment instead of an answer, it's either because I don't have time to do the question justice or because there's some information I feel is needed to give a good answer that I don't have or don't have handy. In this case, I was basically just too lazy. – David Schwartz Mar 16 '16 at 10:42

5 Answers5

3

The size of each int is 4 so the sizeof v should then be 25*4 bytes seemingly but in effect, it is still 16! Why?

You're confusing sizeof(std::vector) and std::vector::size(), the former will return the size of vector itself, not including the size of elements it holds. The latter will return the count of the elements, you can get all their size by std::vector::size() * sizeof(int).

so why is it 16? And why 16 and not another number?

What is sizeof(std::vector) depends on implmentation, mostly implemented with three pointers. For some cases (such as debug mode) the size might increase for the convenience.

Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

std::vector is typically a structure which contains two elements: pointer (array) of its elements and size of the array (number of elements).

As size is sizeof(void *) and the pointer is also sizeof(void *), the size of the structure is 2*sizeof(void *) which is 16.

The number of elements has nothing to do with the size as the elements are allocated on the heap.

EDIT: As M.M mentioned, the implementation could be different, like the pointer, start, end, allocatedSize. So in 32-bit environment that should be 3*sizeof(size_t)+sizeof(void *) which might be the case here. Even the original could work with start hardcoded to 0 and allocatedSize computed by masking end so really dependent on implementation. But the point remains the same.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
  • 4
    The vector needs at least 3 numbers or pointers (start, end, capacity), so a size of 16 probably indicates 3 4-byte pointers plus some bookkeeping – M.M Mar 15 '16 at 07:00
  • I think you misinterpreted what @MM says. You need three pieces of information to satisfy the `std::vector` specification. You need `begin()`, `end()`, `size()` and `capacity()` all to be O(1). – juanchopanza Mar 15 '16 at 07:18
  • @juanchopanza : They would still be - in case `start` was hardcoded to index `0`, the `size` and `end` would be the same. And `capacity` would be computed as `(size&(size-1))<<1`. The performance would be pretty much the same apart from operation removing the element from the beginning. Even with the 4-field implementation `start` and `end` are preferably integers (`size_t`) as they don't need to be adjusted after each reallocation. But as I said - it really may vary from implementation to implementation. – Zbynek Vyskovsky - kvr000 Mar 15 '16 at 07:59
0

sizeof is evaluated at compile time, so it only counts the size of the variables declared in the class, which probably includes a couple of counters and a pointer. It's what the pointer points to that varies with the size, but the compiler doesn't know about that.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

The size can be explained using pointers which can be: 1) begin of vector 2) end of vector and 3) vector's capacity. So it would be more of like implementation dependent and it will change for different implementation.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

You seem to be mixing "array" with "vector". If you have a local array, sizeof will provide the size of the array indeed. However, vector is not an array. It is a class, a container from STL guaranteeing that the memory contents are located within a single block of memory (that may get relocated, if vector grows).

Now, if you take a look at the std::vector implementation, you'll notice it contains fields (at least in MSVC 14.0):

 size_type _Count = 0;
 typename _Alloc_types::_Alty _Alval;   // allocator object (from base)
 _Mylast
 _Myfirst

That could sum up to 16 bytes under your implementation (note: experience may vary).

hauron
  • 4,550
  • 5
  • 35
  • 52