Copying dynamic array to MxArray object using memcpy in c++
10 views (last 30 days)
Show older comments
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?
0 Comments
Accepted Answer
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).
0 Comments
More Answers (1)
Lauren
on 28 Jun 2012
Edited: Lauren
on 28 Jun 2012
4 Comments
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
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.
See Also
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!