The normal implementation of std::vector<T, A> is to have a pointer to have three pointers plus, for stateful allocators, whatever it takes to maintain the allocator:
- A pointer to the start of the vector.
- A pointer to the end of the vector or the number of elements in the vector.
- A pointer to the end of the allocated memory or the number of elements allocated.
When putting this into a type, it will likely be padded to 4 words to improve access times. When you combine a vector like this with two more data members, you'll naturally get a type which occupies 8 words, three of which are to align the type for fast access.
If you really care about the size of your structs containing vector because the vector is normally empty and only rarely contains data, you'd probably prefer an implementation with a different layout: The vector would still need to start the information mentioned above but it could start the data with the allocated buffer: When allocating memory, the vector would allocate extra space to prepend its administration information to the actual values and store a pointer to the allocated data (probably to the first element which, however, makes recovery of the administration information not portable).
Using a representation just described, the size of the vector would be one word and the total size of your struct would be three words plus padding, i.e., probably 4 words. The better size is traded for a small overhead when the size or the capacity of the vector is needed (e.g., when using begin() and `end()).
In general, the size of the vectors tends not to matter because the actual memory consumption of the vectors is down to the elements in the vector.