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

C++ MxCalloc和MxFree与OpenMP结果双重免费或损坏,c++,c,matlab,openmp,mex,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.

这个问题涉及到大量的代码,所以我希望通过一些示例代码给出一些想法。如果有什么我似乎遗漏了,请评论,我会补充更多。无论如何,我有一个使用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
调用不是线程安全的事实

我还尝试添加一个
关键
部分,如下所示:

#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);
}
}   
代码仍然不起作用,并导致类似的错误消息。所以我的问题是:
mxFree
mxCalloc
是否完全非线程安全?因为它们仅在由单个线程调用时工作,即使由其他线程独立调用(由
critical
部分保证),函数仍将失败?如果有任何提示或建议,我将不胜感激。我在考虑用
std::vectors
resize
替换mxCalloc调用,但我想在更改一堆代码之前先知道发生了什么

更新 我只是浏览了一下我的代码,用
resize
向量代替
mxCalloc
mxFree
,这就解决了我遇到的所有问题。仅供将来参考,绝对避免在任何并行区域使用MEXAPI。即使您使用了
临界
部分,它仍然会导致我的linux系统崩溃。这个问题实际上被掩盖了一段时间,因为这个问题没有发生在我使用Windows7的笔记本电脑上

。据MathWorks支持团队称:

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

然而,似乎有些MEX API函数,如
mexErrMsgIdAndTxt
。动态内存分配似乎仍在黑名单上


不要使用
mxMalloc
mxMalloc
,而是使用
malloc
calloc
(或
new
delete[]
)。

foo
只是一个对象。这意味着内存块只有一个存储位置。多个线程都将使用同一个存储位置并产生问题。是否要多个foo对象,每个线程一个?你想要一个单一的内存分配,多个线程在对象的不同部分工作吗?@Peter可能应该指定,但每个线程有一个
foo
对象。实际上,更具体地说,如果有三个线程,则在并行区域外分配了三个
foo
副本,然后线程号作为参数传递给foo,以确定哪个线程有权访问什么。即使在关键部分使用?我现在会更详细地阅读链接,但我想我会直接问你是否知道。@jucestain当时可能不知道。我认为并发性不是问题所在。规则是不能在派生线程内使用任何MEX API函数(
mx*
MEX*
函数)。但是,值得一试!Chappjc,我想你可能是对的。无论如何,我都要重写它,以避免在并行区域中进行任何
mx*
mex*
调用,这只是为了超级安全。我记得有一段时间我试着用一个侍者酒吧来做这个,即使在一个关键的部分,它仍然失败了。。。正如您所建议的那样,最好避免在并行区域中同时使用API。我会等一会儿,看看是否还会有更多的答案出现,但我觉得你是对的。谢谢。事实上,我甚至不确定通过STL向量分配空间(或者甚至为此而
malloc
)是否是线程安全的。。。这个周末我的工作被裁掉了,哈哈。@jucestain关于线程安全:还有。但是,您当然可以在线程中使用向量和动态分配(
malloc
new
,等等)。没问题。当每个线程重新连接时,只需进行清理。