10

I need to have a fixed-size array of elements and to call on them functions that require to know about how they're placed in memory, in particular:

  • functions like glVertexPointer, that needs to know where the vertices are, how distant they are one from the other and so on. In my case vertices would be members of the elements to store.

  • to get the index of an element within this array, I'd prefer to avoid having an index field within my elements, but would rather play with pointers arithmetic (ie: index of Element *x will be x - & array[0]) -- btw, this sounds dirty to me: is it good practice or should I do something else?


Is it safe to use std::vector for this?

Something makes me think that an std::array would be more appropriate but:

  • Constructor and destructor for my structure will be rarely called: I don't mind about such overhead.

  • I'm going to set the std::vector capacity to size I need (the size that would use for an std::array, thus won't take any overhead due to sporadic reallocation.

  • I don't mind a little space overhead for std::vector's internal structure.

  • I could use the ability to resize the vector (or better: to have a size chosen during setup), and I think there's no way to do this with std::array, since its size is a template parameter (that's too bad: I could do that even with an old C-like array, just dynamically allocating it on the heap).


If std::vector is fine for my purpose I'd like to know into details if it will have some runtime overhead with respect to std::array (or to a plain C array):

I know that it'll call the default constructor for any element once I increase its size (but I guess this won't cost anything if my data has got an empty default constructor?), same for destructor. Anything else?

peoro
  • 25,562
  • 20
  • 98
  • 150
  • You'd better not resize the vector after you've called `glVertexPointer`. Other than that, it'll be fine. – Ben Voigt Dec 26 '10 at 05:16
  • possible duplicate of [Convert std::vector to array](http://stackoverflow.com/questions/3787074/convert-stdvector-to-array) – mmmmmm Nov 01 '13 at 15:09

6 Answers6

5

Vectors are guaranteed to have all elements in contigous memory, so it is safe to use in your scenario. There can be a small performance hit compared to c-style arrays, for instance due to index validations done by the vector implementation. In most cases, the performance is determined by something else though, so I wouldn't worry about that until actual measurements of performance show that this a real problem.

As pointed out by others, make sure that you don't reallocate the vector while you are making use of the data stored in it if you are using pointers to elements (or iterators) to access it.

villintehaspam
  • 8,540
  • 6
  • 45
  • 76
  • The standard doesn't actually require that elements be stored in contiguous memory. – moinudin Dec 24 '10 at 10:54
  • 8
    @marcog: Well, the C++03 standard does. The C++98 did not, but it is nonetheless _always_ the case, see http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/ for a discussion on this. – villintehaspam Dec 24 '10 at 10:57
  • 1
    @vil Thanks for correcting me, I was not aware of the change! – moinudin Dec 24 '10 at 11:01
  • +1 for `In most cases, the performance is determined by something else though` – nimcap Dec 24 '10 at 11:58
  • Please read: [stdvector-is-so-much-slower-than-plain-arrays](http://stackoverflow.com/questions/3664272/stdvector-is-so-much-slower-than-plain-arrays/3664349#3664349) Where we show that there is basically no speed difference between C-arrays and vectors. – Martin York Dec 24 '10 at 12:22
  • @Martin York: I was mostly referring to the checked iterators (http://msdn.microsoft.com/en-us/library/aa985965.aspx) in Visual Studio 2005, that we've had to disable to get the best performance in some code (but are of course leaving them enabled in debug builds). – villintehaspam Dec 24 '10 at 12:35
  • @villintehaspam using [] doesn't do range checking (at least in release builds) but .at() does – Martin Beckett Dec 24 '10 at 20:00
  • @Martin Becket: that is true according to the c++ standard as far as I know, however for Visual Studio range checking is done for [] when checked iterators are used (which they are by default), please see the link above. – villintehaspam Dec 24 '10 at 20:07
  • @villintehaspam - I had thought checked iterators were only on in debug build. Thanks for that, very useful – Martin Beckett Dec 25 '10 at 03:11
2

It's fine to treat the data in a std::vector as an array, get a pointer to the start of it with &v[0]. Obviously if you do anything that can reallocate the data then then you pointers will probably be invalidated.

jcoder
  • 29,554
  • 19
  • 87
  • 130
0

Yep, You can use it as Array in OpenGL :) Example:

glBufferData( GL_ARRAY_BUFFER_ARB, dataVec.size() * sizeof( dataVec[0] ), &dataVec[0], GL_STATIC_DRAW_ARB );

Where dataVec is std::Vector

dikamilo
  • 617
  • 7
  • 7
0

It is even safer than having an array on the stack: how big really is your stack? how big could your array become (fixed size, but the size could be increased in later versions)?

stefaanv
  • 14,072
  • 2
  • 31
  • 53
0

If you really want a std::array you can use boost::array. It is like a common array, but support iterators and you can easily use it with STL algorithms.

bcsanches
  • 2,362
  • 21
  • 32
0

Working in multithreading environment and dynamic memory allocation might cause problem because vector is usually a continuous chunk of memory and of pointers might not!

Armando
  • 688
  • 6
  • 15