Question

I am experimenting with OpenCL to increase the speed of our software. We work with maps a lot and, to simplify, represent a map as a std::vector< std::vector >. The OpenCL API takes raw c-style pointers as arguments, for example int* in the case above.

My questions:

  • Are there implementation guarantees in the stl that vector is, internally, consecutive in memory?
  • Can I safely cast a std::vector to int* and expect that to work?
  • In the case of a vector of vectors, can I still assume this holds true? I would expect the vector to hold other state data, or alignment issues, or maybe something else...
  • What is the best way to approach this? Write a custom 2d data structure that holds an internal, contiguous-in-memory buffer and work with that? I'd have to copy to/from vectors a lot...

Thanks.

Was it helpful?

Solution

Are there implementation guarantees in the stl that vector is, internally, consecutive in memory?

As of C++03, yes, a vector is guaranteed to use contiguous storage. (In C++98, there was an accidental loophole so an implementation could hypothetically use non-contiguous storage, but it was fixed in the 2003 revision of the standard - and no implementation actually used non-contiguous storage because it'd be a terrible idea)

Can I safely cast a std::vector to int* and expect that to work?

The usual way is &v[0]. (&*v.begin() would probably work too, but I seem to recall there's some fluffy wording in the standard that makes this not 100% reliable)

No. Why would you expect that to work? A vector is a class. It is not a pointer. It just contains a pointer.

In the case of a vector of vectors, can I still assume this holds true? I would expect the vector to hold other state data, or alignment issues, or maybe something else...

The vector behaves the same whatever you store in it. If you make a vector of vectors, you end up with an object which contains a pointer to a heap-allocated array, where each element is an object which contains a pointer to a heap-allocated array.

As for how you should approach this, it depends on a lot of factors. How big is your total dataset? You might want to have the entire table allocated contiguously. With a vector of vectors, each row is a separate allocation.

OTHER TIPS

  • Are there implementation guarantees in the stl that vector is,
    internally, consecutive in memory

Yes, it is a dynamic array. Standard guarantees that the objects inside vector are stored consecutively.

  • Can I safely cast a std::vector to int* and expect that to work?

No, but you can use begin() and use that as the pointer.

  • Are there implementation guarantees in the stl that vector is,
    internally, consecutive in memory

No, since vector may contain some internal member variables the whole 2D array will not be continuos memory location

Are there implementation guarantees in the stl that vector is, internally, consecutive in memory?

Although I cannot quote the standards here, I have seen code in high-quality libraries assuming this layout (namely, POCO).

Can I safely cast a std::vector to int* and expect that to work?

Specifically, you cannot recast the vector itself. But, I have seen the following code:

std::vector<int> vec;
int* ptr = &vec[0];

In the case of a vector of vectors, can I still assume this holds true? I would expect the vector to hold other state data, or alignment issues, or maybe something else...

You probably cannot cast a vector of vectors to a linear array. Each vector will reserve its own memory range and you cannot expect all of these ranges to be sequencial.

You mentioned in a comment that you work with up to 2500x2500xsizeof(double) data. In that case, I would suggest using one single vector instead of vector of vectors. Allocate NxM elements in a vector and wrap it in a class exposing two-dimensional indexing if you wish to. You get all the benefits of vector with minimum overhead and all your data is still in contiguous memory for fast processing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top