Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does memcpy fail to copy Eigen matrix data, but std::copy succeed?

When I create a matrix using Eigen, like this:

  Eigen::MatrixXd M(3,3);
  M<< 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 ;
  std::cout<<M<<std::endl;

produces

1 4 7
2 5 8
3 6 9

I can walk with a pointer through the data, printing each element:

  double * d = M.data();
  for(int i = 0;i<M.size();i++)
  {
    std::cout<<*d<<" ";
    d++;
  }
  std::cout<<std::endl;

produces

1 2 3 4 5 6 7 8 9

I can also use std::copy to copy it to an array of the same type on the stack, then print the elements of that array:

  double data_copy[9];
  std::copy(M.data(),M.data()+M.size(),data_copy);
  for(int i = 0;i<M.size();i++)
  {
    std::cout<<data_copy[i]<<" ";
  }
  std::cout<<std::endl;

produces

1 2 3 4 5 6 7 8 9

However, I can't seem to use memcpy to do the equivalent copy. This only manages to copy the first element:

  double data_memcopy[9];
  memcpy(data_memcopy,M.data(),M.size());
  for(int i = 0;i<M.size();i++)
  {
    std::cout<<data_memcopy[i]<<" ";
  }
  std::cout<<std::endl;

produces

1 0 0 0 0 0 0 0 0

Any good reason why memcpy is not doing what I expect it should? (Or am I using it improperly?)

like image 765
Alec Jacobson Avatar asked Feb 13 '12 09:02

Alec Jacobson


1 Answers

You need to multiply by the size of a double:

memcpy(data_memcopy,M.data(),M.size() * sizeof(double));

Otherwise, you are only copying M.size() bytes, and each double is more than one byte on your machine.

So you were probably only writing to the first and second doubles (they probably are 8 bytes on your system, since you copied the first one successfully, and the second double you only probably copied one byte which was likely zeros).

like image 181
Michael Chinen Avatar answered Oct 06 '22 00:10

Michael Chinen