views:

842

answers:

7

My question is simple: are std::vector elements guaranteed to be contiguous? In order word, can I use the pointer to the first element of a std::vector as a C-array?

If my memory serves me well, the C++ standard did not make such guarantee. However, the std::vector requirements were such that it was virtually impossible to meet them if the elements were not contiguous.

Can somebody clarify this?

Example:

std::vector<int> values;
// ... fill up values

if( !values.empty() )
{
    int *array = &values[0];
    for( int i = 0; i < values.size(); ++i )
    {
        int v = array[i];
        // do something with 'v'
    }
}
+2  A: 

Yes, the elements of a std::vector are guaranteed to be contiguous.

Benoît
+1 vote from me. But, why the emoticon? I don't find it funny.
Milan Babuškov
Right. I guess i use too much of those :)
Benoît
+4  A: 

The standard does in fact guarantee that a vector is continuous in memory and that &a[0] can be passed to a C function that expects an array.

The exception to this rule is vector<bool> which only uses one bit per bool thus although it does have continuous memory it can't be used as a bool* (this is widely considered to be a false optimization and a mistake).

BTW, why don't you use iterators? That's what they're for.

Motti
> BTW, why don't you use iterators? That's what they're for.Maybe he read the Alexanrescu's new paper on the topic: http://www.boostcon.com/site-media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Nemanja Trifunovic
Thanks for the link, I'll at it to my reading list (I try not to miss Alexandresu's articles)
Motti
Mwahaha, everyone seems to be talking about that presentation these days. Look, the discussion is still hot about it: http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/9b74808d7d869060
Johannes Schaub - litb
If you read it carefully, Alexandrescu's article doesn't really say "Don't use iterators in C++", it says "Check out D". The approach he describes in that paper is strikingly similar to any existing languages and frameworks that have absorbed the functional heritage (List, Scheme, Haskell) and I seriously doubt whether yet-another-C-based-syntax is an ideal starting point for better list handling. Some time last year I briefly tried to persuade him to turn his considerable talents towards improving an already-established language like C# instead, but with I fear no success! :)
Daniel Earwicker
+1  A: 

cplusplus.com:

Vector containers are implemented as dynamic arrays; Just as regular arrays, vector containers have their elements stored in contiguous storage locations, which means that their elements can be accessed not only using iterators but also using offsets on regular pointers to elements.

Igor Oks
+2  A: 

As other answers have pointed out, the contents of a vector is guaranteed to be continuous (excepting bool's weirding).

The comment that I wanted to add, is that if you do an insertion or a deletion on the vector, which could cause the vector to reallocate it's memory, then you will cause all of your saved pointers and iterators to be invalidated.

sharth
The elements would still be stored in a contiguous memory block, it would just be in a different place. The question was specifically about contiguity.
Dima
But the existing pointers and iterators would be invalidated.
sharth
Good point. You should put that into your answer to clarify what you mean.
Dima
+16  A: 

This was missed from C++98 standard proper but later added as part of a TR. The forthcoming C++0x standard will of course contain this as a requirement.

From n2798 (draft of C++0x):

23.2.6 Class template vector [vector]

1 A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

dirkgently
Mike Caron
so s,TR,TC, :) Actually C++03 is also called C++98-TC1 (technical corrigendum) from what i read
Johannes Schaub - litb
@litb: Correct. I keep forgetting which is which.
dirkgently
+2  A: 

As other's have already said, vector internally uses a contiguous array of objects. Pointers into that array should be treated as invalid whenever any non-const member function is called IIRC.

However, there is an exception!!

vector<bool> has a specialised implementation designed to save space, so that each bool only uses one bit. The underlying array is not a contiguous array of bool and array arithmetic on vector<bool> doesn't work like vector<T> would.

(I suppose it's also possible that this may be true of any specialisation of vector, since we can always implement a new one. However, std::vector<bool> is the only, err, standard specialisation upon which simple pointer arithmetic won't work.)

Wuggy