MxCalloc和MxFree与OpenMP结果双重免费或损坏

时间:2014-06-06 15:08:05

标签: c++ c matlab openmp mex

问题涉及大量代码,因此我希望能够通过一些示例代码了解最新情况。如果有什么我似乎已经遗漏了请评论,我会添加更多。无论如何,我有一个使用openMP的方法的对象:

#pragma omp parallel 
{  
int num_thread = omp_get_thread_num(); 

// This function will allocate and deallocate memory through Mxcalloc and MxFree before returning
foo.get_foo(num_thread);
}   

foo类已在另一个文件中定义(该文件使用-C标志编译)并且已编译并与使用openMP的对象链接。它使用两种方法分配和释放内存:

void foo::alloc(const int &h, const int &w) {
if (value == NULL) {
        width = w;
        height = h;
        value = (double *)mxCalloc(h*w,sizeof(double));
    } else {
        mexPrintf("Memory has already been allocated when attempting to alloc.\n");
    }
}


void foo::free() {
    if (value != NULL) {
        width = 0;
        height = 0;
        mxFree(value);
        value = NULL;
    } else {
        mexPrintf("Memory has not been allocated yet when attempting to free.\n");  
    }
}

代码运行完美的单线程。但是,当使用多个线程运行时,我收到以下错误:

*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: double free or     corruption (out): 0x00007f4118019d20 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: malloc(): memory corruption: 0x00007f4101120541 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: double free or corruption (out): 0x00007f412c011260 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: malloc(): memory corruption: 0x00007f4101120541 ***

现在,如果我删除所有free调用(随后删除所有mxFree调用),并重新编译/重新运行代码,它似乎工作正常(我发现这很奇怪,因为只有在指针没有空的情况下才会调用mxFree,所以我不知道问题是什么。所以我将其缩小到mxFree调用不是线程安全的事实。

我还尝试添加critical部分,如下所示:

#pragma omp parallel 
{                  
int num_thread = omp_get_thread_num();

// This function will allocate and deallocate memory through Mxcalloc and MxFree before returning
#pragma omp critical
{
    foo.get_foo(num_thread);
}
}   

代码仍然不起作用并导致类似的错误消息。所以我的问题是:mxFreemxCalloc完全无线安全 - 它们只在单个线程调用时工作,即使独立调用(由critical部分保证)其他线程的功能仍会失败?我很感激任何提示或建议。我在考虑用std::vectorsresize替换mxCalloc调用,但我想知道在更改一堆代码之前最先发生的事情。

更新 我刚刚浏览了我的代码并使用resize代替mxCallocmxFree的向量来解决我遇到的所有问题。仅供将来参考,绝对避免在任何并行化区域中使用MEX API。即使您使用critical部分,它仍会导致我的Linux系统崩溃。这个问题实际上已经掩盖了一段时间,因为我的笔记本电脑上没有使用Windows 7这个问题。

1 个答案:

答案 0 :(得分:1)

C MEX API is not thread-safe。根据MathWorks支持团队的说法:

  

由于MEX API不是线程安全的,因此在生成的线程中不能使用MEX API函数...

然而,似乎某些 MEX API函数have been made thread-safe,如mexErrMsgIdAndTxt。似乎动态内存分配仍然在黑名单上。

而不是mxMallocmxCalloc,请使用malloccalloc(或newdelete[])。