12

I know you can just do: &theVector[0], but is this standard? Is this behavior always guaranteed?

If not, is there a better, less 'hackish' way to do this?

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • 6
    In C++11 the proper way is `theVector.data()`. – ildjarn Dec 30 '11 at 18:40
  • 3
    Note that `&theVector[0]` does not yield an *array*, but rather a *pointer*. Pointers and arrays are different things in the language, with different types. You cannot *convert* a vector to an array in any standard way, although your approach is one standard way of obtaining a *pointer* to the data. – David Rodríguez - dribeas Dec 30 '11 at 19:26
  • I wouldn't call this hackish as compatibility with C APIs that use array pointers was a design decision in the STL. The alternative, that sometimes is seen &*theVector.begin(), should not be used. – aselle Dec 30 '11 at 19:59
  • @aselle : `&*theVector.begin()` is no better or worse than `&theVector[0]` as long as `theVector` is not a `std::vector`. – ildjarn Dec 30 '11 at 20:26

4 Answers4

20

Yes, that behavior is guaranteed. Although I can't quote it, the standard guarantees that vector elements are stored consecutively in memory to allow this.

There is one exception though:

It will not work for vector<bool> because of a template specialization.

http://en.wikipedia.org/wiki/Sequence_container_%28C%2B%2B%29#Specialization_for_bool

This specialization attempts to save memory by packing bools together in a bit-field. However, it breaks some semantics and as such, &theVector[0] on a vector<bool> will not work.

In any case, vector<bool> is widely considered to be a mistake so the alternative is to use std::deque<bool> instead.

Community
  • 1
  • 1
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • I suppose in that case, I would just have to copy it over using `copy` or something? –  Dec 30 '11 at 18:22
  • 1
    There is another exception: if the vector is empty, you can't use the subscript operator on it. – Dietmar Kühl Dec 30 '11 at 18:26
  • 1
    @JonathanLingle Yes, you can use `std::copy()` to do that. – Mysticial Dec 30 '11 at 18:27
  • @DietmarKühl Ah, yes, of course... since you wouldn't be able to `theVector[0]` in the first place. XD – Mysticial Dec 30 '11 at 18:29
  • 2
    Just another random comment: in C++2011 std::vector has data() member returning a pointer to the first element. This also works for empty vectors – Dietmar Kühl Dec 30 '11 at 18:44
  • If the vector is empty, is `&theVector[0]`? Surely it is? Of course, it can't be dereferenced. But I still think/hope that it is defined and is equal to `(T*)theVector.begin()`. Anyway, maybe the solution to all this is to use `(+theVector.begin())` instead - unary addition converts things to pointers, IIRC. – Aaron McDaid Apr 13 '15 at 15:23
  • @AaronMcDaid: __Point 1:__ `&theVector[0]` is undefined behavior when `theVector.size() == 0`. That means it's defined to nothing. In practice you might get by, but a compiler's optimizers can also play havoc with your code. __Point 2:__ Iterators are not required to support unary +, so there's no guarantee that it does what you want, or anything at all. __Point 3:__ The correct way to get access to the underlying data is currently `theVector.data()`. You'll also get a nice compiler error if you use `std::vector::data()`, because the underlying array doesn't exist. – Bill Lynch Apr 13 '15 at 15:32
  • (deleting and replacing my own comment) I somehow thought that iterators have a conversion operator for pointers, but I'm wrong. Now I'm really confused about what to do if the vector is empty, and you don't have `.data()` (because you are pre-C++11) – Aaron McDaid Apr 13 '15 at 16:11
14

C++11 provides the data() method on std::vector which returns a T*. This allows you to do:

#include <iostream>
#include <vector>

int main()
{
  std::vector<int> vector = {1,2,3,4,5};
  int* array = vector.data();
  std::cout << array[4] << std::endl; //Prints '5'
}

However, doing this (or any of the methods mentioned above) can be dangerous as the pointer could become invalid if the vector is resized. This can be shown with:

#include <iostream>
#include <vector>

int main()
{
  std::vector<int> vector = {1,2,3,4,5};
  int* array = vector.data();

  vector.resize(100); //This will reserve more memory and move the internal array

  //This _may_ end up taking the place of the old array      
  std::vector<int> other = {6,7,8,9,10}; 

  std::cout << array[4] << std::endl; //_May_ now print '10'
}

This could could crash or do just about anything so be careful using this.

Milliams
  • 1,474
  • 3
  • 21
  • 30
1

We can do this using data() method. C++11 provides this method. It returns a pointer to the first element in the vector. vector Even if it is empty, we can call this function itself without problems

  vector<int>v;
  int *arr = v.data();
rashedcs
  • 3,588
  • 2
  • 39
  • 40
0

A less 'hackish' way? Well you could simply copy :

#include <iostream>
#include <vector>
using namespace std;



int main()
{ 
    vector<int> vect0r;
    int array[100];

    //Fill vector
    for(int i = 0; i < 10 ; i++) vect0r.push_back( i ) ;

    //Copy vector to array[ ]
    for(  i = 0; i < vect0r.size(); i++) array[i] = vect0r[i];

    //Dispay array[ ]
    for(  i = 0; i < vect0r.size(); i++)  cout<< array[i] <<" \n";

    cout<<" \n";

return 0;
}

More here : How to convert vector to array in C++

Community
  • 1
  • 1
Software_Designer
  • 8,490
  • 3
  • 24
  • 28