Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is data storage in std::vector continuous? [duplicate]

Tags:

c++

vector

I have a vector of chars and I want to pass it's content as a char* to another function:

void foo(boost::shared_ptr<std::vector<boost::uint8_t> > data)
{
    bar(data->size()?reinterpret_cast<char*>(&(data.get()->front())):NULL);
}

Can I assume that the data is always stored in a contiguous manner? Thanks.

like image 494
Sanich Avatar asked Dec 01 '25 20:12

Sanich


2 Answers

From the 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().

Also do check array being reallocated (invalidating any pointers and iterators) after adding elements to it.

Also check this article:- Cringe not: Vectors are guaranteed to be contiguous

contiguity is in fact part of the vector abstraction. It’s so important, in fact, that when it was discovered that the C++98 standard didn’t completely guarantee contiguity, the C++03 standard was amended to explicitly add the guarantee.

Also from the C++ FAQ

#include <vector>
#include "Foo.h"  /* get class Foo */

// old-style code that wants an array
void f(Foo* array, unsigned numFoos);

void g()
{
  std::vector<Foo> v;
  ...
  f(v.empty() ? NULL : &v[0], v.size());  ← safe
}

The funny expression v.empty() ? NULL : &v[0] simply passes the NULL pointer if v is empty, otherwise passes a pointer to the first (zeroth) element of v. If you know a priori that v is not empty, you can change that to simply &v[0]. In general, it means you are guaranteed that &v[0] + n == &v[n], where v is a std::vector<T> and n is an integer in the range 0 .. v.size()-1.

However v.begin() is not guaranteed to be a T*, which means v.begin() is not guaranteed to be the same as &v[0]:

void g()
{
  std::vector<Foo> v;
  ...
  f(v.begin(), v.size());  ← Error!! Not Guaranteed!!
    ^^^^^^^^^-- cough, choke, gag; not guaranteed to be the same as &v[0]
}
like image 153
Rahul Tripathi Avatar answered Dec 03 '25 11:12

Rahul Tripathi


From Cppreference:

std::vector is a sequence container that encapsulates dynamic size arrays.

The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets on regular pointers to elements.

So yes, the elements are contiguous in memory. That means you can use the underlying data container (which is a T[], that you get with the data() member function) as a classic array.

like image 20
JBL Avatar answered Dec 03 '25 13:12

JBL