-1

I am trying to fill a vector with a matrix of values in c++. I'm not very self confident with this procedure (I don't know well about pointers and I don't know if I need it here) however I am trying this

int auxMat[gray.rows][gray.cols];
vector<int> collectionSum;
collectionSum.push_back(auxMat);

When I try to compile I receive an error which says

invalid arguments 'Candidates are: void push_back(const int &)

Can anyone tell me wether it's possible to do, how can I solve it?

I read something about erasing cache memory, changing my eclipse compiler, my c++ version, however I don't think the problem is so big.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110

2 Answers2

0

You cannot push back a matrix into a vector. What you can do is preallocate memory for your vector (for speeding things up) then use the std::vector<>::assign member function to "copy" from the matrix into the vector:

vector<int> collectionSum(gray.rows * gray.cols); // reserve memory, faster
collectionSum.assign(*auxMat, *auxMat + gray.rows * gray.cols);

This should be pretty fast. Otherwise, you can push back each individual element in a loop.

EDIT

See May I treat a 2D array as a contiguous 1D array? for some technicalities regarding possible undefined behaviour (thanks @juanchopanza for the comment). I believe the code is safe, due to the fact that the storage of the matrix is contiguous.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • I think there's a thing about out of bounds access which makes this technically UB, even though it is hard to think of an implementation where this wouldn't work. I'll see if I can find some links. – juanchopanza Jun 14 '15 at 21:17
  • @juanchopanza actually that's exactly what I was thinking right now... since we do out of bounds, however we have contiguous storage. – vsoftco Jun 14 '15 at 21:18
  • There's this: http://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array – juanchopanza Jun 14 '15 at 21:19
  • @juanchopanza hmm, still not 100% convinced whether the code is 100% safe or not. – vsoftco Jun 14 '15 at 21:23
  • Thanks, @vsoftco. I will try this one... However I already did something with a vector of a vector of a vector of integer (long and slow thing) since I didn't know how to get to the result. – Diego Alejandro Gómez Pardo Jun 15 '15 at 23:04
  • @DiegoAlejandroGómezPardo you should avoid vector of vector if possible, since as you observed things are slow due to cache misses (non-contiguous storage). You can use a "flattened" vector, and emulate 2D-3D access. However, the method above works. – vsoftco Jun 15 '15 at 23:09
0

Because the array auxMat is continuous in memory, you can just copy it directly from memory into your vector. Here, you are telling the vector constructor to copy from the start of auxMat until its end in memory using pointer arithmetic:

std::vector<int> collectionSum(auxMat, auxMat + (gray.rows * gray.cols));

EDIT:

Sorry, I read your question as being a 1D array (int*) rather than a 2D (int**) array. I honestly recommend switching over to a 1D array because often it is faster and easier to work with. Depending on whether your using row-first order or column-first order, you can access the element you want by:

elem = y * width + x;    // for row-first order
elem = x * height + y;   // for column-first order

For instance:

// Create a 3x3 matrix but represent it continuously as a 1D array
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
const unsigned width = 3;
const unsigned height = 3;
for (int y = 0; y < height; ++y)
{
    for (int x = 0; x < width; ++x)
    {
       printf("%d ", A[y * width + x]);
    }
    printf("\n");
}
Dawud
  • 19
  • 2