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

6 ビュー (過去 30 日間)
ShimShim
ShimShim 2018 年 4 月 10 日
コメント済み: ShimShim 2018 年 4 月 17 日
Hi I am trying to copy a n*m matrix defined by dynamic memory allocation to mxArray, and send it to matlab the matrix is sent right in size but false in values. I appreciate if anyone can help me to find what is wrong. here is the code
double **dataDMA;
int m = 3, n = 3, c = 0;
mxArray *matDDMA;
dataDMA = (double **)calloc(sizeof(double *), m); // number of columns
for (int i = 0; i < m; ++i)
{
dataDMA[i] = (double *)calloc(sizeof(double), n); // number of rows
}
printf("\nMatrix created by Dynamic Memory Allocation:\n");
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
dataDMA[i][j] = c+1;
printf("%g ", dataDMA[i][j]);
c = c + 1;
}
printf("\n");
}
matDDMA=mxCreateDoubleMatrix(m, n, mxREAL);
if (matDDMA == NULL)
{
printf("Unable to create mxArray matDDMA.\n");
return(EXIT_FAILURE);
}
memcpy((void *)mxGetPr(matDDMA), (void *)dataDMA, m*n *sizeof(double));
engPutVariable(ep, "matDDMA", matDDMA);
engEvalString(ep, "matDDMA");

採用された回答

James Tursa
James Tursa 2018 年 4 月 11 日
編集済み: James Tursa 2018 年 4 月 11 日
Two fundamental problems:
1) You can't guarantee that successive calls to calloc( ) will produce memory segments that are adjacent to each other in memory. So the entire concept of using a single memcpy to copy such memory as one big block is non-conforming. If might happen to work if you are lucky, and then the next time the program will bomb because you weren't lucky. If you want to copy it all as one single block of memory, then you need to allocate it as such. E.g.,
dataDMA = (double **)calloc(sizeof(double *), m); // number of columns
dataDMA[0] = (double *)calloc(sizeof(double), n*m); // entire block of double memory
for (int i = 1; i < m; ++i) // <-- start loop indexing at 1
{
dataDMA[i] = dataDMA[i-1] + n; // next column is n elements over
}
Then, when you are done with this memory you only have two free( ) calls to make:
free(dataDMA[0]);
free(dataDMA);
2) The dataDMA pointer points to the column address array, not to the double data itself. So your memcpy source address is wrong. It should be this:
memcpy(mxGetPr(matDDMA), dataDMA[0], m*n *sizeof(double)); // don't need (void *) here
  6 件のコメント
James Tursa
James Tursa 2018 年 4 月 17 日
Does the first value scan in correctly? I would work on just getting this first number to work properly, and then move on to the rest of the file.
ShimShim
ShimShim 2018 年 4 月 17 日
James, I changed all doubles to float, also used mxArray* matdata1DMA = mxCreateNumericMatrix(mm, nn, mxSINGLE_CLASS, mxREAL); instead of mxArray* matdata1DMA = mxCreateNumericMatrix(mm, nn, mxREAL); which worked.
The only matter was with the image which was flipped, so I changed the indexes in the for loop to data1DMA[i][j] to data1DMA[j][i] when scanning as below;
for (int i = 0; i < mm; i++)
{
for (int j = 0; j < nn; j++)
{
fscanf(input_file, "%f ",&data1DMA[j][i]);
}
}
Thanks a lot for your help.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeC Shared Library Integration についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by