5

I was wondering if there is a clever way of presenting the information in a vector as a 1D array. Example: Let's create a vector of vectors of 5x3 int elements

vector< vector<int>> iVector;
ivector.resize( 5 );
for(i = 0; i < 5; i++){
    iVector[i].resize(3);
}

But now I want this structure to be converted into a 1D array:

int* myArray = new int[5*3];

So I could access each element which I want as follows:

for (i =0;i < 5; i++)
  for(j =0; j< 3; j++)
      myArray[i*3+j] = ...

I know I could just copy the vector to the array element by element, but I was wondering if there is a method that directly addresses the vector to array conversion. I also know that the vector can me addressed as iVector[i][j] , but unfortunately it needs to be an array as it will be sent to a GPU and GPUs dont understand vectors.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
Manolete
  • 3,431
  • 7
  • 54
  • 92

4 Answers4

2

Just use std::copy 5 times.

int* ptrArray = myArray;
for (i =0;i < 5; i++) {
  std::copy(iVector[i].begin(), iVector[i].end(), ptrArray);
  ptrArray += iVector[i].size();
}
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
2

There's really nothing you can do here except copy it into an array. The GPU will not understand any abstraction you create any more than it can understand std::vector. All you can do is make an array and copy it over.

Puppy
  • 144,682
  • 38
  • 256
  • 465
1

Vectors supposed to store the elements in a linear fashion, so in theory you can refer to the entire underlying vector (only a single vector):

std::vector<int> numbers;
int data[4] = &(numbers[0]);

Similarily, perhaps you can try the same approach for the 2D version. However in your place I would consider to use a class that is specifically designed to handle matrices (it is easy to write one similar to std::vector().

progician
  • 910
  • 8
  • 15
  • This approach will not work for a vector of vectors, as the [vectors are not stored contiguously](https://stackoverflow.com/a/10898084) – Magnus Apr 19 '19 at 11:53
1

Or you can use plain old C.

You first initialize the array size to be the number of rows * the number of columns your vector of vectors has. Then you use memcpy to copy each vector to the array.

vector<vector<int> > v = { {1,2},{3,4},{5,6} }; //v is 3 by 2 matrix 
int *arr = (int*)malloc( (3*2) * sizeof(int)); // arr has size 3*2 = 6
for (int i = 0; i < 3; i++)
    memcpy(arr + v[i].size() * i, &(v[i][0]), v[i].size() * sizeof(int));

Here's a function that I wrote that does this for you:

template<typename T>
T *vectorToArray(vector<vector<T> > const &v) {
    T *rv = (T*)malloc((v.size()*v[0].size()) * sizeof(T)); //Assuming all rows have the same size
    for (unsigned i = 0; i < v.size(); i++)
        memcpy(rv + v[i].size() * i, &(v[i][0]), v[i].size() * sizeof(T));
    return rv;
}

So now you can do something like this:

vector<vector<int> > v = { {1,2},{3,4},{5,6} }; //v is 3 by 2 matrix 
int *arr = vectorToArray(v);

I hope this helps

Panos
  • 1,764
  • 21
  • 23