MATLAB: Using matlab engine from c++: How to convert a int** into mxArray*

engine

Hi,
I am opening matlab engine from c++, and I want to find the inverse matrix of a matrix. I have tried to convert the int** matrix into mxArray* in different ways, without success:
S = mxCreateDoubleMatrix(v->getCols(), v->getRows(), mxREAL);
memcpy(mxGetPr(S), v->getOpSet(), sizeof(v->getOpSet()));
or:
S = mxCreateDoubleMatrix(v->getCols(), v->getRows(), mxREAL);
mxSetPr(S,(double*)v->getOpSet());
double *acc =mxGetPr(S);
for(p=0;p<mxGetM(S); p++){
for(p1=0 ; p1<mxGetN(S) ; p1++){
cout<< acc[mxGetM(S)*p1+p];
}
}
cout<<endl;
On my first try, the first 2 elements are exponential and weird, and the rest of the matrix is 0.
on my second try, all of the elements are weird, and I get segmentation fault.
have someone have some experience with this and knows how to make the convertion?
another problem I have is that I can't get the result in an array, only as string. meaning,how can I get 'x' as a double array (not mxArray) after this:
buffer[BUFSIZE] = '\0';
engOutputBuffer(ep, buffer, BUFSIZE);
engEvalString(ep, "x = mldivide(S,T)");
(after this code, buffer contains the right result, but if I do:
D=engGetVariable(ep, "x");
D doesn't contain the right result.
is there a way to do this right?
thank you.

Best Answer

Repeating your comment above for how you allocate opSet:
opSet = new double*[columns];
for (p=0; p<columns ; p++)
opSet[p] = new double[rows];
Since you allocate it this way, it is NOT guaranteed to be contiguous in memory as you claim. What you have done is first allocate an array of row pointers, and then each row pointer gets allocated a row of memory and those rows are NOT required to be next to each other in memory. They might happen to be for a particular run, but they might not be for another run. This is not a good way to allocate a matrix. What you should be doing is allocate the entire matrix as one contiguous block, and then if you want row pointers you can set them to point as desired. e.g., something like this:
opSet = new double*[columns];
opSet[0] = new double[rows*columns];
for (p=1; p<columns ; p++)
opSet[p] = opSet[p-1] + rows;
That way you are guaranteed that the matrix is contiguous in memory and you can reliably use memcpy etc to copy the entire contents at once by just using the address in opSet[0]. Also, it is easier to clean up since you only have to delete opSet[0] and opSet (i.e., you don't need a for loop to delete opSet[1] through opSet[columns-1] since they were not separately allocated).
On the memcpy side, be sure you are using the v->opSet()[0] address, not just v->opSet() as you show above. The first is the address of the double data, while the second is the address of the row pointer array (not what you want to copy).
For the number of bytes to copy, you also incorrectly use sizeof(v->getOpSet()), which will give you the size of a pointer (typically 4 or 8 depending on your system). You should be using something like v->getCols() * v->getRows() instead.