First time here? Check out the FAQ!

Ask Your Question
1

findContours - OpenCV 2.4.5, Heap Corruption

asked May 13 '13

SinisterMJ gravatar image

updated May 13 '13

I have read this happening on different questions here, but no answer worked so far, so this is my code:

cv::Mat* CVMatFromUC(unsigned char* input, int width, int height)
{
    cv::Mat* resultMat = new cv::Mat(height, width, CV_8UC1);
    resultMat->data = input;
    return resultMat;
}

unsigned char* UCFromMatUC(cv::Mat* input)
{
    int size = input->size.p[0] * input->size.p[1];
    unsigned char* result = new unsigned char[size];
    memcpy(result, input->data, size);
    return result;
}

unsigned char* CannyEdgeCV(unsigned char* input, int width, int height)
{
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;

    cv::Mat* inp = CVMatFromUC(input, width, height);
    cv::Mat canny_output;
    cv::Mat* outp = new cv::Mat(height, width, CV_8UC1);
    cv::blur(*inp, *outp, cv::Size(3,3));
    cv::Canny(*outp, canny_output, 10.0, 15.0);
    if(!canny_output.type()==CV_8UC1){
        return NULL;
    }

    cv::findContours(canny_output, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
    //cv::findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

    unsigned char* result = UCFromMatUC(inp);
    delete outp;
    delete inp;
    return result;
}

Originally I was only using the canny edge map, but later on I wanted to test the results of the contour functionality.

The Canny Edge works fine, and I get an image as expected (C:\fakepath\EdgeMap.bmp, but the findContours (both the one in code and the commented version) fail with a heap corruption error. What causes this?

The entry point for this is the CannyEdgeCV()

Preview: (hide)

Comments

Do you use Visual Studio as IDE? If so try to use MFC as shared library.

AntonM gravatar imageAntonM (Dec 11 '13)edit

as a general advice - do not use Pointers to cv::mMat.

it's a 'smart pointer' already, chances are high, you're thrashing the internal refcount this way.

berak gravatar imageberak (Jan 28 '15)edit

2 answers

Sort by » oldest newest most voted
0

answered Mar 7 '16

lowlander256 gravatar image

updated Mar 8 '16

I encountered the same problem with the following environment:

  • Compiler: VC2013
  • OpenCV: 3.0(self build)
  • Build Configuration: Debug(x86)

After some investigating, I found the cause of it finally. The root cause is the use of uncorresponding malloc/free and this is a design defect of cv::OutputArray.

Passing a std::vector as a cv::OutputArray, cv::OutputArray allocates a memory when the vector is empty, but the caller must deallocate the memory. In general, alloc/dealloc functions must be used correspondingly, so the current implementation of cv::OutputArray is essentially a bug which should be fixed.


Detailed Explanation

In a debug session, I identified the moments of allocation/deallocation of a problematic memory block.

Their callstacks are as follows:

Allocation

msvcr120d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp)  486    C++
msvcr120d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp)  239 C++
msvcr120d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine)  302   C++
msvcr120d.dll!malloc(unsigned int nSize)  56   C++
msvcr120d.dll!operator new(unsigned int size)  59  C++
opencv_world300d.dll!std::_Allocate<cv::Vec<int,4> >(unsigned int _Count, cv::Vec<int,4> * __formal)  28   C++
opencv_world300d.dll!std::allocator<cv::Vec<int,4> >::allocate(unsigned int _Count)  578   C++
opencv_world300d.dll!std::_Wrap_alloc<std::allocator<cv::Vec<int,4> > >::allocate(unsigned int _Count)  848    C++
opencv_world300d.dll!std::vector<cv::Vec<int,4>,std::allocator<cv::Vec<int,4> > >::_Reallocate(unsigned int _Count)  1588  C++
opencv_world300d.dll!std::vector<cv::Vec<int,4>,std::allocator<cv::Vec<int,4> > >::_Reserve(unsigned int _Count)  1619 C++
opencv_world300d.dll!std::vector<cv::Vec<int,4>,std::allocator<cv::Vec<int,4> > >::resize(unsigned int _Newsize)  1107 C++
opencv_world300d.dll!cv::_OutputArray::create(int d, const int * sizes, int mtype, int i, bool allowTransposed, int fixedDepthMask)  2343  C++
opencv_world300d.dll!cv::_OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, int fixedDepthMask)  2206  C++
opencv_world300d.dll!cv::findContours(const cv::_InputOutputArray & _image, const cv::_OutputArray & _contours, const cv::_OutputArray & _hierarchy, int mode, int method, cv::Point_<int> offset)  1743   C++

Deallocation

MyApp.exe!free_dbg_nolock(void * const block, const int block_use)  892    C++
MyApp.exe!_free_dbg(void * block, int block_use)  1011 C++
MyApp.exe!operator delete(void * block)  17    C++
MyApp.exe!std::_Deallocate(void * _Ptr, unsigned int _Count, unsigned int _Sz)  138    C++
MyApp.exe!std::allocator<cv::Vec<int,4> >::deallocate(cv::Vec<int,4> * _Ptr, unsigned int _Count)  638 C++
MyApp.exe!std::_Wrap_alloc<std::allocator<cv::Vec<int,4> > >::deallocate(cv::Vec<int,4> * _Ptr, unsigned int _Count)  910  C++
MyApp.exe!std::vector<cv::Vec<int,4>,std::allocator<cv::Vec<int,4> > >::_Tidy()  1662  C++
MyApp.exe!std::vector<cv::Vec<int,4>,std::allocator<cv::Vec<int,4 ...
(more)
Preview: (hide)
0

answered Jan 28 '15

CVBear gravatar image

updated Jan 28 '15

I encountered with the same problem in case building project with MS VS2010 building platform toolset and OpenCV version 2.4.10.

In my case the reason was in incorrect path to the OpenCV bin folder. It was "C:\Program Files (x86)\opencv\build\x86\vc12\bin".

But for MS VS2010 need to use "C:\Program Files (x86)\opencv\build\x86\vc10\bin". Just add path in system PATH variable to where located "opencv_core2410d.dll" for your specific OpenCV and MSVS version or copy it in folder where located your executable.

Preview: (hide)

Question Tools

2 followers

Stats

Asked: May 13 '13

Seen: 3,199 times

Last updated: Mar 08 '16