# std::vector : packed storage ?

7 replies to this topic

### #1polyvertex

Member

• Members
• 32 posts

Posted 29 October 2008 - 09:42 AM

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();

### #2Nick

Senior Member

• Members
• 1227 posts

Posted 29 October 2008 - 10:41 AM

polyvertex said:

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.

Quote

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.

### #3Nick

Senior Member

• Members
• 1227 posts

Posted 29 October 2008 - 12:27 PM

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

### #4polyvertex

Member

• Members
• 32 posts

Posted 29 October 2008 - 12:51 PM

Quote

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

Quote

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.

### #5.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 30 October 2008 - 05:03 PM

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
-
Currently working on: the 3D engine for Tomb Raider.

### #6polyvertex

Member

• Members
• 32 posts

Posted 31 October 2008 - 09:44 AM

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

### #7kusma

Valued Member

• Members
• 163 posts

Posted 31 October 2008 - 11:08 AM

.oisyn said:

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?

### #8.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 31 October 2008 - 12:22 PM

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.cpprefere.../wiki/stl/start