Error in copying element of one array to another in C++

This is a very simple issue that for some reason I am not sure why I keep getting wrong. I am basically trying to copy array ``n`` to array ``dummy`` as the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct real_buffer
{
  double* a;
  int rows;
  int cols;

  double& operator()(int i, int j) const { return a[i * cols + j]; }
};

real_buffer my_fftw_allocate_real(int x, int y) { return real_buffer{ fftw_alloc_real(x * y), x, y }; }

int main(){	
static const int nx = 10;
static const int ny = 10;
for (int i = 0; i < nx; i++){
		for (int j = 0; j < ny+1; j++){
n[j + (ny+1)*i] = //initialized 


  }
}
//copy n to array dummy
real_buffer dummy = my_fftw_allocate_real((ny+1), nx);
	for(int i = 0; i< nx; i++){//for(int i = 0; i< nx+1; i++){
		for(int j = 0; j< ny+1; j++){
		dummy(j,i) = n[j + (ny+1)*i];
		}
	}

}

However, this returns the following arrays of ``n`` and ``dummy`` respectively:
1
2
3
4
5
6
7
8
9
10
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.23e+00  +5.00e+00  +1.23e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00
+1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00  +1.00e+00


1
2
3
4
5
6
7
8
9
10
11
      1.00      1.00      1.00      1.00      1.00      5.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.23      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00      1.00
      1.00      1.00      1.00      1.00      1.23      1.00      1.00      1.00      1.00      1.00

The two arrays clearly are off, I usually use ``memcpy`` but it wasn't really working for this struct here. Thanks a lot.
Last edited on
You appear to have your rows and columns the wrong way round in one array. In your "output", n has 10 rows and dummy has 11.

Your code also appears to confuse an array called n[] with one called ne[].
As written, dummy's buffer is assigned transpose(ne). But since the transposition of an X by Y matrix is a Y by X matrix, to actually finish the transposition you'd also have to swap dummy.rows and dummy.cols, or dummy will be the wrong shape (unless it's square).

BTW, this operation should be in a function so that it can be thoroughly tested once and re-used.

I usually use ``memcpy`` but it wasn't really working for this struct here.

Why is the first matrix 10x10 but the second matrix is 11x10? A typo? How should you copy a 10x10 matrix to an 11x10 matrix?

If the matrices are actually the same size, memcpy should work unless you are trying to swap storage orders.
Last edited on
@lastchance
You appear to have your rows and columns the wrong way round in one array. In your "output", n has 10 rows and dummy has 11.

You're right, thanks a lot!
@mbozzi
If the matrices are actually the same size, memcpy should work unless you are trying to swap storage orders.

They are the same size, but I was getting an error when using memcpy. Something like:
no suitable conversion function from "real_buffer" to "void *" exists
then you did something wrong.
specifically, if its the same code you had before, its real_buffer.a that can be treated as a pointer, not the struct itself. you forgot to get down to the right level. Memcpy is sort of playing with fire, though. Its fast, but it takes some care to avoid mistakes.

transpose in place isnt too hard to cook up if you don't need all this copying nonsense.
Last edited on
You can do the copy with something like

1
2
3
4
5
6
7
8
9
[[nodiscard]] 
real_buffer from_plain_array(double* p, int rows, int cols)
{
  real_buffer result = my_fftw_allocate_real(rows, cols); 
  std::memcpy(result.a, p, sizeof(*result.a) * rows * cols); 
  return result;
}
// later on
real_buffer dummy = from_plain_array(ne, ny + 1, nx);

Last edited on
Topic archived. No new replies allowed.