Ask Your Question
1

findContours - OpenCV 2.4.5, Heap Corruption

asked 2013-05-13 06:28:09 -0600

SinisterMJ gravatar image

updated 2013-05-13 06:34:30 -0600

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()

edit retag flag offensive close merge delete

Comments

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

AntonM gravatar imageAntonM ( 2013-12-11 07:57:37 -0600 )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 ( 2015-01-28 16:22:39 -0600 )edit

2 answers

Sort by » oldest newest most voted
0

answered 2016-03-07 01:28:35 -0600

lowlander256 gravatar image

updated 2016-03-08 00:39:44 -0600

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)
edit flag offensive delete link more
0

answered 2015-01-28 16:14:50 -0600

CVBear gravatar image

updated 2015-01-28 16:49:42 -0600

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.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2013-05-13 06:28:09 -0600

Seen: 3,163 times

Last updated: Mar 08 '16