Ask Your Question
1

chamerMatching malloc error

asked 2014-02-13 16:21:37 -0600

bluestreak209 gravatar image

updated 2018-10-04 23:47:36 -0600

I am having an error trying to do chamfer matching. Somewhere within the call to chamerMatching, I get the error:

malloc: * error for object 0x104044000: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug

Here is the code:

Mat img = imread(argc == 3 ? argv[1] : "X077_03.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
Mat tpl = imread(argc == 3 ? argv[2] : "X077_03.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Canny(img, img, 5, 50, 3);
Canny(tpl, tpl, 5, 50, 3);
vector<vector<Point> > results;
vector<float> costs;
int best = chamerMatching( img, tpl, results, costs );

Does anyone have a guess as to what could be going on?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2014-03-11 11:13:05 -0600

aecins gravatar image

I have had a similar issue that might be related to yours. I was trying to run the sample Chmafer matching code from OpenCV (/trunk/opencv/samples/cpp/chamfer.cpp) and I would get the following error:

* glibc detected :double free or corruption (!prev): 0x0000000000745bb0 **

The reason is that in function chamerMatching(img, tpl, results, costs) a template is created and then a reference to it is added inside matcher_ object:

ChamferMatcher::Template template_(templ, (float)templScale);
ChamferMatcher::Matches match_instances = matcher_.matching(template_, img);

As a result when the function returns template_ is destroyed first and then when matcher_ is destroyed it tries to destroy the same template again hence you gen an error.

A quick fix to it is to modify the destructor of Matching() and to comment out the line that deletes templates.

    ~Matching()
    {
        for (size_t i = 0; i<templates.size(); i++) {
            //delete templates[i];
        }
    }

Note, however, that this solution is just a hack that I used to get the demo working. There might be other ways templates can be added to Matching object and those need to be deleted otherwise you will get memory leak.

edit flag offensive delete link more

Comments

would you be so nice to make an issue here , so someone can have a go at fixing it ?

berak gravatar imageberak ( 2014-03-11 11:30:41 -0600 )edit
aecins gravatar imageaecins ( 2014-03-11 12:04:45 -0600 )edit

well done, thanks a lot.

berak gravatar imageberak ( 2014-03-11 12:09:07 -0600 )edit

Have you found another better solution? I don't understand very well yours. Why don't run the sample? I have the same error than you

fortes_23 gravatar imagefortes_23 ( 2015-01-06 14:00:45 -0600 )edit
0

answered 2016-08-29 14:27:04 -0600

Charles Tallman gravatar image

updated 2016-08-29 14:57:33 -0600

I found that the Template ownership and lifetime issues get quite complicated. At the heart of the problem is the ChamferMatcher::Template::rescale function, which can either return "this" or a new-allocated Template object. A template can also hold scaled templates in an internal vector. Template pointers can also be copied to Matching, etc.

If one is willing to use the modern C++11 standard library, the problems can be resolved with std::shared_ptr, which does reference counting and only destroys an object when the last pointer to it is destroyed.

std::shared_ptr<ChamferMatcher::Template> ChamferMatcher::Template::rescale(float new_scale)
{

if (fabs(scale - new_scale) < 1e-6) return shared_from_this();

for (size_t i=0;i<scaled_templates.size();++i) {
    if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
        return scaled_templates[i];
    }
}

float scale_factor = new_scale/scale;

auto tpl = std::make_shared<Template>();
tpl->scale = new_scale;

tpl->center.x = int(center.x*scale_factor+0.5);
tpl->center.y = int(center.y*scale_factor+0.5);

tpl->size.width = int(size.width*scale_factor+0.5);
tpl->size.height = int(size.height*scale_factor+0.5);

tpl->coords.resize(coords.size());
tpl->orientations.resize(orientations.size());
for (size_t i=0;i<coords.size();++i) {
    tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
    tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
    tpl->orientations[i] = orientations[i];
}
scaled_templates.push_back(tpl);

return tpl;

}

All uses of Template* should be replaced with std::shared_ptr<Template> and all uses of const Template * with std::shared_ptr< const Template >. Then all the raw delete operations are not necessary, and the matches can be used safely.

edit flag offensive delete link more

Comments

  • the legacy chamerMatching has been removed entirely in the current api, so that's no more a problem.
  • opencv has cv::Ptr, which does exactly the same as std::shared_ptr (without need for c++11 support)
berak gravatar imageberak ( 2016-08-30 01:10:50 -0600 )edit

It's good to know about cv::Ptr. However, it seems to be lacking std::enable_shared_from_this, and the std::make_shared has better template support for construction of arbitrary objects.

Charles Tallman gravatar imageCharles Tallman ( 2016-08-30 12:52:10 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2014-02-13 16:21:37 -0600

Seen: 1,890 times

Last updated: Aug 29 '16