Ask Your Question

cvReshapeMatND after cvCreateMatND,memory can not be released.

asked 2014-02-17 03:19:20 -0500

amazingguo gravatar image

updated 2014-02-17 06:05:23 -0500

I use OpenCV 2.4.8 with VS2010. When I try to release some memory using the following code, the memory is not released. I think something went wrong with the cvReshapeMatND() function. If you comment this function out, the memory can be released.(Please open the windows task manager and watch the memory of the excution.) Please shed me some light about this problem, thank you very much!

#include "stdafx.h"
#include <opencv.hpp>
#include <Windows.h>

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
    Mat Ca = Mat::zeros(7000, 10000, CV_32FC1);
    for(int i = 0; i < 1000; i++)
        int new_size[2] = {7000, 10000};    

        CvMatND TpCa = Ca;
        CvMatND *Caimg1 = cvCreateMatND(2, new_size, CV_32F);

        cvReshapeMatND(&TpCa, sizeof(CvMatND), Caimg1, 0, 2, new_size);

    return 0;
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2014-02-17 03:34:52 -0500

updated 2014-02-17 03:35:38 -0500

If you comment out the release function call, the memory is released because your variable Caimg1 is a local one, it will be free automatically. Your code contains error that can lead to a memory leak: CvMatND *Caimg1 = cvCreateMatND(2, new_size, CV_32F); this statement allocates a memory and Caimg1 points to that, but the next statement: cvReshapeMatND(&TpCa, sizeof(CvMatND), Caimg1, 0, 2, new_size); will make Caimg1 points to memory data of TpCa, this causes the memory unmanaged. Indeed, the function cvReshapeMatND create a new header matrix and changes the data pointer (see more at

edit flag offensive delete link more


Thank you! You are right! This is indeed why the memory is lost somehow... I figured out the solution:use cvCreateMatNDHeader() instead of the cvCreateMatND(), that solved the problem.

amazingguo gravatar imageamazingguo ( 2014-02-17 05:48:57 -0500 )edit

answered 2014-02-17 03:51:11 -0500

berak gravatar image

updated 2014-02-17 03:55:22 -0500

consistent usage of the c++ api will solve all your problems:

 Mat Ca = Mat::zeros(7000, 10000, CV_32FC1);
 Mat Cb = Ca.reshape(1,7000);

that's it already. no manual allocation, no manual release required.

(also you don't need MatND anymore, its an alias for Mat)

do yourself (and us) a favour, and get rid of the outdated c-api calls there

edit flag offensive delete link more


Thank you for you answer! I know Mat class can automatically manage the memory which is more convinient and safer. But I really needs a method to convert a 3-dimensional Mat to a 2-dimensional Mat, so I have to use that CvMatND struct as a bridge to do the convertion. As far as I know the cvReshapeMatND() is the only method that can do so(the normal reshape method seems to only deal with the 2-dimensional Mat). The program above is only a small demo, not my original code. It will be very appreciated if you can give a better sollution, thank you very much!

amazingguo gravatar imageamazingguo ( 2014-02-17 05:58:56 -0500 )edit

you probably need to show your 3-dimensional Mat then.

berak gravatar imageberak ( 2014-02-17 06:18:48 -0500 )edit

This is how I do the 3-dimensional to 2-dimensional convert for now(Ca -> Ca2) I wonder if there is any better solution.

int mat_size[3] = {100, 700, 1000};
Mat Ca = Mat(3, mat_size, CV_32FC1);

int new_size[2] = {7000, 10000};    

CvMatND TpCa = Ca;
CvMatND *Caimg1 = cvCreateMatNDHeader(2, new_size, CV_32F);

Caimg1 = (CvMatND*)cvReshapeMatND(&amp;TpCa, sizeof(CvMatND), Caimg1, 0, 2, new_size);

Mat Ca2(Caimg1);
amazingguo gravatar imageamazingguo ( 2014-02-17 19:59:05 -0500 )edit

Question Tools


Asked: 2014-02-17 03:19:20 -0500

Seen: 239 times

Last updated: Feb 17 '14