14

I'm using memcpy to copy the content of std:vectors<> to primitve Arrays. For datatypes like int, float, double etc. it worked well. As I started to copy a boolvector I encountered a problem namely I got strange values.

First I started to make an test output for a float vector:

std::vector<float> test1 (3,0);

cout << "Sizeof test1[0] : " << sizeof(test1[0]) << endl
     << "Memoryaddress 0: " << &test1[0] << endl
     << "Memoryaddress 1: " << &test1[1] << endl
     << "Memoryaddress 2: " << &test1[2] << endl;

The output is:

Sizeof test1[0]: 4
Memoryaddress 0: 02793820
Memoryaddress 1: 02793824
Memoryaddress 2: 02793828

And this is what I expect. The float size is 4 Byte and the distance to the next float value is 4 Byte. When I do this for bool the output looks like this:

std::vector<bool> test (3,0);

cout << "Sizeof test[0]: " << sizeof(test[0]) << endl
     << "Memoryaddress 0: " << &test[0] << endl
     << "Memoryaddress 1: " << &test[1] << endl
     << "Memoryaddress 2: " << &test[2] << endl;

The output is:

Sizeof test[0]: 16
Memoryaddress 0: 011EF94C
Memoryaddress 1: 011EF93C
Memoryaddress 2: 011EF92C

Why is the size of bool 16 Byte? It seems like a total overkill to me. Are there explanations for this?

David G
  • 94,763
  • 41
  • 167
  • 253
akristmann
  • 434
  • 1
  • 7
  • 15
  • 1
    `&test[0]` isn't what you think it is. Check its type! – Marc Glisse Apr 04 '13 at 10:57
  • 2
    Your title is misleading, you never actually check the size of `std::vector`. – jrok Apr 04 '13 at 10:58
  • You can't take the `sizeof` something that's smaller than one character. The `sizeof` operator returns the size in integer multiples of the size of a character. – David Schwartz Apr 04 '13 at 10:59
  • 1
    @DavidSchwartz: True, but that doesn't explain why it's 16 bytes rather than 1. – Mike Seymour Apr 04 '13 at 11:15
  • @MikeSeymour: The point is to show that since no answer would make sense given the OP's assumptions, those assumptions can't be right. It makes no sense to expect this to work. – David Schwartz Apr 04 '13 at 11:19
  • 1
    @DavidSchwartz: Unless the assumption is that `test[0]` is a reference to `bool`, just as `test1[0]` is a reference to `float` - quite a reasonable assumption if you don't know about the `vector` specialisation. `bool` itself is not "smaller than one character", and one would be surprised if it were larger than that. – Mike Seymour Apr 04 '13 at 11:24

2 Answers2

29

Unlike other specialisations of vector, vector<bool> does not manage a dynamic array of bool objects. Instead, it is supposed to pack the boolean values into a single bit each.

Since individual bits are not addressable, test[0] cannot simply be a reference to bool. Instead, it is an class type vector<bool>::reference that can be converted to bool (to get the value), and assigned from bool (to modify the vector element).

This means that vector<bool> doesn't entirely meet the requirements of a standard container, and can't be used if you need references or pointers to its elements. If you do require a "real" container with addressable elements, consider vector<char> or deque<bool> instead.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    @akristmann You can also take a look at http://en.cppreference.com/w/cpp/utility/bitset which *might* be suitable for you. – Red XIII Apr 04 '13 at 15:02
4

std::vector<bool> is a specialized version of vector, which is optimizes for space.

  • The storage is not necessarily an array of bool values, but the library implementation may optimize storage so that each value is stored in a single bit.
  • Elements are not constructed using the allocator object, but their value is directly set on the proper bit in the internal storage.

More information: http://www.cplusplus.com/reference/vector/vector-bool/

nmikhailov
  • 1,413
  • 14
  • 24