0
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

0
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.

0
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’?

0
101 Oct 29, 2008 at 12:51

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.

0
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 :)

0
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 :)

0
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?

0
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)