Copying dynamic array to MxArray object using memcpy in c++

10 views (last 30 days)
I am writing a c++ program that calls that Matlab Engine. I am getting an error when I try to use memcpy for a dynamically allocated multi-dimensional array. I have a type definition as follows in my header file:
typedef double* dblArrayptr;
My array definition in my function is as as follows:
dblArrayptr *A;
A = new dblArrayptr [2*NUMROWS];
for (int i=0;i<2*NUMROWS;i++)
A[i] = new double [2*NUMROWS];
I initialize this matrix A with some values and then try to use the memcpy command as follows: (note: this matrix has 44 rows and 44 columns).
memcpy((void *)mxGetPr(A_m), (void *)A,1936*sizeof(double));
I receive a memory access violation error. Access violation reading location.
This memcpy command seems to work ok if I have a single array (44x1) of type double.
Do I have to do an element by element copy?

Accepted Answer

James Tursa
James Tursa on 28 Jun 2012
Problem #1)
Your method is a poor way to allocate a 2D matrix because it does not require that all of the individual columns are contiguous in memory, hence you cannot reliably use memcpy on the entire data set at once to copy the contents into an mxArray. In the code snippet below, the memory behind A[i] is not necessarily contiguous to the memory behind A[i+1] etc.
for (int i=0;i<2*NUMROWS;i++)
A[i] = new double [2*NUMROWS];
Problem #2)
Your memcpy is not even copying the data memory behind the pointers, it is copying the pointers themselves (i.e., the A array). Remember, A is not an array of doubles, it is (effectively) an array of pointers to doubles.
memcpy((void *)mxGetPr(A_m), (void *)A,1936*sizeof(double));
Solutions:
A poor way to do this would be to copy each column individually to the appropriate place in the mxArray data area in a loop. Gets the job done but it is rather inefficient and your code is more complex than it needs to be.
A better way to do this would be to allocate your entire 2D matrix all at once. That will allow you to copy the data to the mxArray data area in one fell swoop. If you really want the A[i] column pointers then just point them to the appropriate places within the contiguous 2D data area.
The best way is to avoid new altogether. Just create your mxArray up front and use mxGetPr to get a pointer into the data area. If you want the A[i] column pointers then just point them to the appropriate places within this contiguous data area (again avoiding the new).

More Answers (1)

Lauren
Lauren on 28 Jun 2012
Edited: Lauren on 28 Jun 2012
James, Thank you for your answer. In response to problem 1, my program works with matrices of varying problem sizes, which is determined at runtime based on the input file. Therefore, I have to wait until runtime to allocate the memory based on input.
In response to problem 2, thank you for pointing on my 'error with pointers'.
For solution option 1, I thought about doing that but couldn't find anything in the help that indicated how to access a column or an array.
For solution option 2, I am assuming you mean to define the matrix up front as 44x44. This would mean every time I want to run this program for a different size, I have to change the code and recompile. (If I am understanding this correctly).
I will try option 3. Thank you.
  4 Comments
Abigail Cember
Abigail Cember on 23 Aug 2017
I know this question was asked a while ago, but I'll try my luck... Why was it necessary here to declare i as mwSize instead of int?
James Tursa
James Tursa on 23 Aug 2017
It wasn't. int would have worked just as well. Having said that, there is a possible subtle issue depending on how NUMCOLUMNS is defined. If it is defined as mwSize, then it could end up being a size_t, which is unsigned. Then if i is an int, which is signed, you are mixing signed and unsigned integers in downstream code. Now this can be done correctly of course if you are careful, but it is something you as the programmer need to be aware of to make sure it is not an issue in your downstream code.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!