是否可以在Matlab上创建子数组而不使用额外的内存?

时间:2017-11-29 09:44:50

标签: matlab pointers memory mex

好吧,我正在尝试在Matlab上实现一个算法。它需要在for循环中使用一个高维数组的切片。当我尝试使用逻辑索引时,Matlab会创建该切片的附加副本,因为我的数组很大,所以需要花费很多时间。

slice = x(startInd:endInd);

我要做的是使用该切片而不复制它。我只需要切片数据来输入线性运算符。我不会在迭代期间更新该部分。

为此,我尝试编写一个输出为double的Mex文件 类型数组,其大小等于预期的切片数据大小。

plhs[0] = mxCreateUninitNumericMatrix(0, 0, mxDOUBLE_CLASS,mxREAL); % initialize but do not allocate any additional memory
ptr1 = mxGetPr(prhs[0]); % get the pointer of the input data

然后将输出的指针设置为输入数据的起始索引。

mxSetPr(plhs[0], ptr1+startInd);
mxSetM(plhs[0], 1);
mxSetN(plhs[0], (endInd-startInd)); % Update the dimensions as intended

当我将起始索引设置为零时,它可以正常工作。当我试图给予 除0之外的其他值,Mex文件编译时没有错误,但是当调用Mex函数时Matlab崩溃。

slice = mex_slicer(x, startInd, endInd);

这可能是什么问题?

2 个答案:

答案 0 :(得分:0)

将数据指针分配给数组的方式,意味着MATLAB将在删除数组或为其分配其他内容时尝试释放该内存。尝试使用free未获得的指针调用malloc将导致崩溃。

不幸的是,MATLAB不支持“视图”,指向不同数组部分的数组。所以没有办法做你想做的事。

另一种解决方案是:

  • 以不同方式存储您的数据,因此索引时间不会太长(例如在较小的数组中)?

  • 在MEX文件中的C或C ++中执行所有计算,您可以非常简单地指向较大数据块的子范围。

答案 1 :(得分:0)

请参阅此FEX提交,了解如何创建“指向”现有变量内部数据的MATLAB变量。您既可以将其作为共享数据副本来设计为安全(但会产生一些额外的开销),也可以作为不受保护的直接引用(更快但如果您没有正确清除它,则可能会导致MATLAB崩溃)。

https://www.mathworks.com/matlabcentral/fileexchange/65842-sharedchild-creates-a-shared-data-copy-of-a-contiguous-subsection-of-an-existing-variable