std::vector : packed storage ?

1b1be3e6a679f9e62120cf062f16e130
0
polyvertex 101 Oct 29, 2008 at 09:42

Hi all,

Here is a little question about the std::vector container.

class MyClass
{
public :
  // ...
  std::vector<unsigned char> buffer;
};

I make use of the std::vector container instead of dynamically allocating an array of chars to create my “buffer” because I don’t want to have to implement the “=” operator of MyClass by myself and because performance is far from being a premium requirement in this case.
Thus, here, I will never call the erase(), insert() or even the push_back() methods.

My question is, does the STL specify that std::vector must store its elements in an aligned fashion ?

Do the following lines ensure that I can address the entire content of my “buffer” ?

MyClass c;
unsigned char* p1 = c.buffer[0];
unsigned char* p2 = c.buffer.at(0);
unsigned char* p3 = *c.buffer.begin();

7 Replies

Please log in or register to post a reply.

99f6aeec9715bb034bba93ba2a7eb360
0
Nick 102 Oct 29, 2008 at 10:41

@polyvertex

My question is, does the STL specify that std::vector must store its elements in an aligned fashion ?

Yes, this is guaranteed: vector. Beware that this is the only STL class with well-defined memory layout though.

Do the following lines ensure that I can address the entire content of my “buffer” ?

You forgot to use the address operator (&). Other than that it should work.

99f6aeec9715bb034bba93ba2a7eb360
0
Nick 102 Oct 29, 2008 at 12:27

By the way, there’s not a lot of reason to use use classic pointers when working with vectors. Any compiler will optimize the accesses into a plain array access. Also, to step over the elements you should use an iterator whenever possible. This makes it trivial to switch to other containers. But don’t over-engineer it either (yeah there’s a fine line).

What will be the use of your ‘buffer’?

1b1be3e6a679f9e62120cf062f16e130
0
polyvertex 101 Oct 29, 2008 at 12:51

Thank you for your answers Nick.

Also, to step over the elements you should use an iterator whenever possible. This makes it trivial to switch to other containers. But don’t over-engineer it either (yeah there’s a fine line).

Yes, that’s what I usually do, and this is why I was confused in this case :)

By the way, there’s not a lot of reason to use use classic pointers when working with vectors.

What will be the use of your ‘buffer’?

I’m using an API which is expecting from the caller a buffer of data (input only) and the size of this buffer is not predictable before runtime.

As I said, the only reason I want to use the std::vector container instead of a dynamically allocated array of chars (new[] or malloc) is because I want to let C++ to manage copying of MyClass objects (i.e. not to implement MyClass::operator= by myself).
I find it less error prone this way…

Since you’re telling me that there’s no problem for the vector container, to fill-in the vector, I planned to it this way :

c.buffer.resize(buffer_size);
memcpy(&c.buffer[0], source_buffer_ptr, buffer_size);

Of course I will test it before… :)

Thanks again.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 30, 2008 at 17:03

Or simply

c.buffer.assign(source_buffer_ptr, source_buffer_ptr + buffer_size);

(if source_buffer_ptr is an unsigned char *, otherwise you’ll have to cast it).

Btw, even though Nick is correct about vector storing it’s data contiguously, beware of std::vector<bool>. This is a specialization which stores the individual bools as a single bit, and therefore has special accessing types to manipulate the vector, as in, vector<bool>::operator[] for example does not return a reference to bool, but rather a proxy object that acts as a single bit embedded in a memory location. So you can’t turn a vector<bool> into a bool*. This is the only exception, and the C++ committee has admitted this was a mistake, so you better steer clear of it as it’s life is uncertain :)

1b1be3e6a679f9e62120cf062f16e130
0
polyvertex 101 Oct 31, 2008 at 09:44

Oh yes, even better, I forgot the assign() method… Thanks !
BTW, good to know that std::vector<bool> specialization is in danger :)

C4b4ac681e11772d2e07ed9a84cffe3f
0
kusma 101 Oct 31, 2008 at 11:08

@.oisyn

Or simply

c.buffer.assign(source_buffer_ptr, source_buffer_ptr + buffer_size);

Is vector::assign standard? I can’t find it on the SGI reference page?

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Oct 31, 2008 at 12:22

That’s because the SGI implementation isn’t standard (that’s the official “STL”, which was added to the ISO C++ standard with some modifications)

http://www.cppreference.com/wiki/stl/start