Watch out for std::vector size

A quick reminder based on my experience. Recently I stumbled upon this great snippet, which lets me send graphics card a vector of data:

It is a useful one, but at first I started getting problems when calling OpenGL drawArrays* methods.

It took me a while to realize the problem appears because of the way I filled the vector with data. Of course real code was quite complicated, but it boils down to:

  1. Allocate vector
  2. Reserve memory using precalculatedSize
  3. Get iterator: std::vector::begin
  4. Loop with unsigned int i = 0..precalculatedSize-1, set data[i]

Looks fine so far. (OK, maybe using iterator and iteration variable is a bad idea, but that’s the free-time code, right? 🙂 ).

$ clang++ -std=c++11 a.cpp; ./a.exe
expectedSize = 100
data.size() = 0
data.capacity() = 100

data[2891] = 32768

…And the problem is direct memory access. Vector is told to reserve memory, but not to resize itself (compare std::vector::reserve vs std::vector::resize). In my case OpenGL got a buffer of size 0 and crashed.

The solution is quite simple: either to resize vector and use array access braces or reserve memory and push_back data.

Surprisingly, iterator incrementation worked fine in this example, also for “indexes” outside vector. I also made a simple test and in my implementation (clang++ 3.9 x86_64-w64-windows-gnu). Vector as above after reserving 100 fields returned (random) number for first 2892 fields.

Would you spot it at first sight? 😉