C 为什么使用mex时matlab内存不足
如果我在循环中使用mex文件,Matlab将内存不足。我想这是内存泄漏造成的。mxMalloc变量由mxFree释放,但我无法使用mxDestroyArray(plhs[0])销毁mxCreateNumericArray变量 mex文件来自屏幕外工具箱。代码如下C 为什么使用mex时matlab内存不足,c,matlab,opengl,memory-leaks,mex,C,Matlab,Opengl,Memory Leaks,Mex,如果我在循环中使用mex文件,Matlab将内存不足。我想这是内存泄漏造成的。mxMalloc变量由mxFree释放,但我无法使用mxDestroyArray(plhs[0])销毁mxCreateNumericArray变量 mex文件来自屏幕外工具箱。代码如下 #include "mex.h" #include "math.h" #include "OffscreenGL.h" #include "OffscreenCommon.h" void drawPatchAndConvert(GLui
#include "mex.h"
#include "math.h"
#include "OffscreenGL.h"
#include "OffscreenCommon.h"
void drawPatchAndConvert(GLuint listName, GLubyte *imageBuffer, unsigned int imgHeight, unsigned int imgWidth, unsigned int zoomFactor = 1)
{
// This is a temporary bug fix for Nvidia's open program
// seems the width of the pixel has to be a multiple of 4
// for other width, we have to pad the width and remove it later
unsigned int paddedWidth = imgWidth * zoomFactor % 4;
if (paddedWidth != 0){
paddedWidth = 4 - paddedWidth + imgWidth * zoomFactor;
}else {
paddedWidth = imgWidth * zoomFactor;
}
unsigned char *paddedImgBuffer = (unsigned char *)mxMalloc(paddedWidth * imgHeight * zoomFactor * MAX_COLOR_CHANNEL * sizeof(GL_UNSIGNED_BYTE));
drawPatch(listName, paddedImgBuffer, imgHeight, imgWidth, zoomFactor);
// reorder the pixel data for the opengl to matlab conversion
unsigned int imgSize = imgHeight * imgWidth * zoomFactor * zoomFactor;
unsigned int imgSize2 = imgSize * 2;
unsigned int matlabImgIndex = 0;
unsigned int oglImageIndex = 0;
for (int j = 0; j < imgWidth * zoomFactor; j++) {
for (int i = 0; i < imgHeight * zoomFactor; i++, matlabImgIndex++) {
oglImageIndex = (j + (imgHeight*zoomFactor -1-i) * paddedWidth) * 3;
imageBuffer[matlabImgIndex] = paddedImgBuffer[oglImageIndex];
imageBuffer[matlabImgIndex + imgSize] = paddedImgBuffer[oglImageIndex + 1];
imageBuffer[matlabImgIndex + imgSize2] = paddedImgBuffer[oglImageIndex + 2];
}
}
mxFree(paddedImgBuffer);
}
static void renderColorMesh(double *FM, int fNum, double *VM, int vNum, float *ColorM, int colorNum,const mxArray *CamParamS, double *imgSizeV, double *zNearFarV, unsigned int zoomFactor,unsigned char *imgBuffer)
{
cameraSetup(CamParamS, zNearFarV[0], zNearFarV[1], (unsigned int) imgSizeV[0], (unsigned int) imgSizeV[1], zoomFactor);
#ifndef NDEBUG
mexPrintf("Start to create the display list: fNum=%d, vNum=%d, colorNum=%d\n", fNum, vNum, colorNum);
#endif
GLuint list = createDisplayListWithColor(FM, fNum, VM, vNum, ColorM, colorNum);
#ifndef NDEBUG
mexPrintf("Start to draw the patch\n");
#endif
drawPatchAndConvert(list, imgBuffer, (int) imgSizeV[0], (int) imgSizeV[1], zoomFactor);
}
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
// get the vertex array, face array, and color array
double *FM = mxGetPr(prhs[0]);
int fNum = mxGetM(prhs[0]);
double *VM = mxGetPr(prhs[1]);
int vNum = mxGetM(prhs[1]);
float *ColorM = (float *)mxGetData(prhs[2]);
int colorNum = mxGetM(prhs[2]);
// get the camera parameters
const mxArray *CamParamS = prhs[3];
double *imgSizeV = mxGetPr(prhs[4]);
double *zNearFarV = mxGetPr(prhs[5]);
double zoomFactor = mxGetScalar(prhs[6]);
OffscreenGL offscreenGL((int)(imgSizeV[0] * zoomFactor), (int) (imgSizeV[1] * zoomFactor));
int output3Size[3];
unsigned char *imgBuffer;
if (offscreenGL.RGB8Setup()) {
//mexPrintf("OpenGLCanvas setup Successful\n");
output3Size[0] = (int) (imgSizeV[0] * zoomFactor);
output3Size[1] = (int) (imgSizeV[1] * zoomFactor);
output3Size[2] = 3;
plhs[0] = mxCreateNumericArray(3, output3Size, mxUINT8_CLASS, mxREAL);
imgBuffer = (unsigned char *) mxGetData(plhs[0]);
renderColorMesh(FM, fNum, VM, vNum, ColorM, colorNum, CamParamS, imgSizeV,
zNearFarV, (unsigned int) zoomFactor, imgBuffer);
} else {
mexPrintf("OpenGLCanvas setup failed\n");
}
}
#包括“mex.h”
#包括“math.h”
#包括“OffscreenGL.h”
#包括“OffscreenCommon.h”
void drawPatchAndConvert(GLuint listName,GLubyte*imageBuffer,unsigned int imgHeight,unsigned int imgWidth,unsigned int zoomFactor=1)
{
//这是Nvidia开放程序的临时错误修复
//似乎像素的宽度必须是4的倍数
//对于其他宽度,我们必须填充宽度,然后将其删除
unsigned int paddedWidth=imgWidth*zoomFactor%4;
如果(填充宽度!=0){
paddedWidth=4-paddedWidth+imgWidth*zoomFactor;
}否则{
paddedWidth=imgWidth*zoomFactor;
}
无符号字符*paddeMgBuffer=(无符号字符*)mxMalloc(paddedWidth*imghight*zoomFactor*MAX_COLOR_CHANNEL*sizeof(GL_unsigned_BYTE));
drawPatch(列表名、PaddeMgBuffer、imgHeight、imgWidth、zoomFactor);
//为opengl到matlab转换重新排序像素数据
unsigned int imgSize=imgHeight*imgWidth*zoomFactor*zoomFactor;
无符号整数imgSize2=imgSize*2;
无符号int-matlabImgIndex=0;
无符号int-oglImageIndex=0;
对于(int j=0;j
此行可疑:
paddedWidth = 4 - paddedWidth + imgWidth * zoomFactor;
它仅用几个字节填充整个放大的行。我想你的意思是
paddedWidth = (4 - paddedWidth + imgWidth) * zoomFactor;
在您显示的代码中没有调用
mxDestroyArray
?另外,如果调用egx=mxCreateNumericArray(…)
,则释放它的逻辑步骤是mxDestroyArray(x)
,而不是mxDestroyArray(x[0])
@stijn:该行创建MEX函数的LHS输出,因此如果要将结果返回到MATLAB,显然不应该销毁。user2613981:我没有看到任何明显的内存泄漏,我认为你正在使用的库是罪魁祸首,而不是你的代码…谢谢你的回复@Amro是正确的,这不是因为这个MEX文件。这是因为该文件使用了一个函数,'GLuint list=createDisplayListWithColor(FM,fNum,VM,vNum,ColorM,colorNum);'openGL在createDisplayListWithColor函数中的问题如下所示glColor3f(ColorM[vIndex],ColorM[vIndex+vNum],ColorM[vIndex+vNum2]);'但我不知道glColor3f是如何导致内存泄漏的。最后我使用了glClear,但无法解决它。@user2613981:如果它解决了您的问题,您应该将其作为答案发布。另一方面,当您将来遇到此类问题时,第一件容易尝试的事情是使用mxMalloc
而不是malloc
,这样分配的内存将在MATLAB内存管理器中注册,并在MEX函数退出时自动释放(以防您忘记手动mxFree
它)好的,我刚刚看到你的第二条评论,也许这还没有解决。。我还没有看过工具箱代码,所以我不能说该函数中的内存泄漏到底在哪里。现在我建议您附加一个调试器并逐步完成C代码,也许您可以通过这种方式发现问题。。。