在从Matlab Compiler Runtime返回的mxArray对象上调用mxDestroyArray

use*_*155 6 matlab memory-management segmentation-fault matlab-compiler

我们一直在与从Matlab编译器创建的库连接.我们的问题与从库返回的数组有关.

一旦我们完成了数组,我们就想释放内存,但这样做会导致偶尔的分段错误.

这是Matlab库(bugtest.m)::

function x = bugtest(y)

x = y.^2;
Run Code Online (Sandbox Code Playgroud)

这是我们用来构建它的命令(创建libbugtest.so,和libbugtest.h)::

mcc -v -W lib:libbugtest -T link:lib bugtest.m
Run Code Online (Sandbox Code Playgroud)

这是我们的C测试程序(bug_destroyarray.c)::

#include <stdio.h>
#include <stdlib.h>

#include "mclmcrrt.h"
#include "libbugtest.h"

#define TESTS 15000

int main(int argc, char **argv) 
{
    const char *opts[] = {"-nojvm", "-singleCompThread"};
    mclInitializeApplication(opts, 2);  
    libbugtestInitialize();

    mxArray *output;
    mxArray *input;
    double *data;
    bool result;
    int count;

    for (count = 0; count < TESTS; count++) {

        input = mxCreateDoubleMatrix(4, 1, mxREAL);
        data = mxGetPr(input); data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;

        output = NULL;
        result = mlfBugtest(1, &output, input);
        if (result) {
            /* HERE IS THE PROBLEMATIC LINE */
            /*mxDestroyArray(output);*/
        }

        mxDestroyArray(input);
    }

    libbugtestTerminate();
    mclTerminateApplication();
}
Run Code Online (Sandbox Code Playgroud)

这是我们如何编译C程序(创建bug_destroyarray)::

mbuild -v bug_destroyarray.c libbugtest.so
Run Code Online (Sandbox Code Playgroud)

我们认为这mxDestroyArray(output)是有问题的.

我们运行以下命令来测试崩溃:

  • 在32个群集节点中的每个节点上.
  • bug_destroyarray.
  • 监视分段错误的输出.

大约有10%的时间是崩溃.如果这在节点之间是独立的,那么您可能会认为它在大约0.3%的时间内崩溃.

当我们拿出那条有问题的线时,我们无法使它崩溃.

但是,如果不包含此行,则内存使用量会逐渐增加.

从我们所做的研究来看,似乎我们应该破坏返回的数组,如果没有,我们如何阻止泄漏内存?

谢谢.

Amr*_*mro 0

一些注意事项:

我尝试了你的代码,它工作得很好,没有段错误。由于我无法访问计算机集群,因此我的测试仅在本地计算机(带有 R2013a 的 WinXP)上进行。

我必须删除两个 MCR 初始化选项才能使其正常工作(特别是nojvm导致运行时错误)。以下是稍作修改的完整代码。运行大约需要10秒:

#include <stdio.h>
#include <stdlib.h>
#include "libbugtest.h"

#define TESTS 15000

int main() 
{
    mxArray *output, *input;
    double *data;
    int count;
    bool result;

    if( !mclInitializeApplication(NULL,0) ) {
        fprintf(stderr, "Could not initialize the application.\n");
        return EXIT_FAILURE;
    }
    if ( !libbugtestInitialize() ) {
        fprintf(stderr, "Could not initialize the library.\n");
        return EXIT_FAILURE;
    }

    for (count = 0; count < TESTS; count++) {
        input = mxCreateDoubleMatrix(4, 1, mxREAL);
        data = mxGetPr(input);
        data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;

        output = NULL;
        result = mlfBugtest(1, &output, input);
        if (!result) {
            fprintf(stderr, "call failed on count=%d\n", count);
            return EXIT_FAILURE;
        }

        mxDestroyArray(output); output = NULL;
        mxDestroyArray(input); input = NULL;
    }

    libbugtestTerminate();
    mclTerminateApplication();

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

此外,Windows 上的编译步骤有点不同,因为我们静态链接导入库(它插入一个存根以在运行时动态加载 DLL):

mbuild -v -I. bug_destroyarray.c libbugtest.lib
Run Code Online (Sandbox Code Playgroud)