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

MxCalloc and MxFree with OpenMP results double free or corruption

本文关键字:免费 损坏 结果 MxFree OpenMP MxCalloc      更新时间:2023-10-16

这个问题涉及到大量的代码,所以我将尝试用一些示例代码来给出一个想法。如果有什么我似乎遗漏了,请评论,我会补充更多。总之,我有一个对象,它的方法使用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的笔记本电脑上没有出现。

cmex API不是线程安全的。根据MathWorks支持团队:

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

然而,似乎一些 MEX API函数已经变成线程安全的,比如mexErrMsgIdAndTxt。动态内存分配似乎还在黑名单上。

使用malloccalloc(或newdelete[])代替mxMallocmxCalloc