如何在 Matlab 中正确使用在 C++ dll 中动态分配的内存

How to properly use memory dynamically allocated in C++ dll within Matlab

我编写了一个 C++ 接口 dll 来调用英特尔集成性能基元 (IPP) 库中的一些关键图像处理统计测量方法,以便我们可以利用 SIMD 功能。我能够使用 calllib

将两个 2D Matlab 数组传递到函数中
A = single( rand(3,4) );
B = single( rand(3,2) );

pOut = calllib('IPPInterface', 'myFunc', A' , B' , size(A,1), size(A,2) , size(B,1), size(B,2) );

在 C++ 中,myFunc 具有以下签名和正文片段...

float* myFunc( float A[] , float B[] , int nRowsA , int nColsA , int nRowsB , int nColsB )
{
    ...
    float[] pDst = new float[nRowsA*nColsA];
    ...
    return pDst;
}

我不确定的是 Matlab 如何以及是否成功从内存中删除此类缓冲区。他们最终在 Matlab 过程中结束为 lib.pointers:

>> class(pOut)

ans =

lib.pointer

我只是好奇我正在做的事情是否是个坏主意,或者如果调用 Matlab 的 clear pOut 会处理所有事情并避免可能的内存泄漏。

所以我一直在通过在 Matlab 中创建两个数组来进行一些内存测试,如下所示...

I = single( rand( 1200 , 1600 ) );
T = single( rand( 100  , 100  ) );

然后我将我的函数放入一个循环中,将内存使用情况打印到文本文件并清除返回的 libpointer。

for i = 1:10000
    lp = calllib('IPPInterface', 'myFunc', I , T , size(I,2) , size(I,1) , size(T,2) , size(T,1) );
    clear lp;

    [u,s] = memory;

    fprintf( fileID ,'%13g    %13s\n' ,  u.MemUsedMATLAB , s.SystemMemory.Available );
end 

走那条路肯定会填满我的物理内存,如下所示,并且让我相信我所做的是一个坏主意,Matlab 不会在像时尚这样的自动垃圾收集中处理这个问题。

>> memory
Maximum possible array:              38799 MB (4.068e+010 bytes) *
Memory available for all arrays:     38799 MB (4.068e+010 bytes) *
Memory used by MATLAB:               21393 MB (2.243e+010 bytes)
Physical Memory (RAM):               34814 MB (3.650e+010 bytes)

*  Limited by System Memory (physical + swap file) available.
>> clear all
>> memory
Maximum possible array:              38803 MB (4.069e+010 bytes) *
Memory available for all arrays:     38803 MB (4.069e+010 bytes) *
Memory used by MATLAB:               21388 MB (2.243e+010 bytes)
Physical Memory (RAM):               34814 MB (3.650e+010 bytes)

*  Limited by System Memory (physical + swap file) available.
>> 

如果我关闭 Matlab,OS 自然会回收所有内存。

在浏览 Matlab 的网站后,我确实找到了一个足够接近的示例,该示例在共享库中动态分配了一个 c-struct,后来 Matlab 不得不调用在同一个库中编写的函数,该函数的唯一任务是删除那个结构。

Working with Pointer Arguments; Multilevel Pointers

这个例子是正确的,在实现对共享库的简单接口调用以释放我的数组并在完成后使用它之后

void deallocateArray( float* A )
{
    delete[] A;
}

内存配置文件是平坦的,整个 10000 次迭代完成得更快...

for i = 1:10000
    lp = calllib('IPPInterface', 'myFunc', I , T , size(I,2) , size(I,1) , size(T,2) , size(T,1) );
    calllib('IPPInterface', 'deallocateArray', lp );
    clear lp;

    [u,s] = memory;

    fprintf( fileID ,'%13g    %13s\n' ,  u.MemUsedMATLAB , s.SystemMemory.Available );
end