Ask Your Question
0

ConjGradSolver: how to properly use setFunction to avoid assertion failure?

asked 2016-10-19 05:31:04 -0600

Rackbox gravatar image

updated 2016-10-19 07:04:09 -0600

I'm using cv::ConjGradSolver in OpenCV 3.0 and I'm facing a failure in a debug assertion when exiting the scope of my function. Here is my minimal (not) working code:

void Fitting()
{
TorusFunction TorusMinimizationFunction = TorusFunction();
Ptr<ConjGradSolver> TorusFitting = ConjGradSolver::create();
TorusFitting->setFunction(&TorusMinimizationFunction);
}

The TorusFunction class is my implementation of the virtual class MinProblemSolver::Function: if you need further details I can add the code.

When reaching the end of the Fitting function, a debug assertion fails (_BLOCK_TYPE_IS_VALID), probably because of a double destroy of the same thing.

Looking inside the unit tests code of the ConjGradSolver class, I found this way of doing things which do works:

void Fitting()
{
TorusFunction* ptr = new TorusFunction();
Ptr<MinProblemSolver::Function> ptr_F = Ptr<MinProblemSolver::Function>(ptr);
Ptr<ConjGradSolver> TorusFitting = ConjGradSolver::create();
TorusFitting->setFunction(ptr_F);
}

Where is my error in the first implementation? What are the differences between the two versions? The first version was the one that I wrote myself, and it looks more linear to me, while the second one requires an explicit new (but no destroy). Note that both versions execute the calculations correctly (which I've not reported for brevity).

Thanks in advance!

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-10-19 06:00:21 -0600

berak gravatar image

updated 2016-10-19 06:34:27 -0600

since your Solver takes a Ptr<Function> as argument, this is, what you should provide.

your 1st version, providing the addess of a (stack created) Function crashes, because the internal cv::Ptr will try to release it, and call delete on something, that was not created with new .

so please try like this:

void Fitting()
{
Ptr<MinProblemSolver::Function> ptr = makePtr<TorusFunction>();
Ptr<ConjGradSolver> TorusFitting = ConjGradSolver::create();
TorusFitting->setFunction(ptr);
}
edit flag offensive delete link more

Comments

Your solution is very similar to the second version of my first post, am I right? According to the documentation, makePtr<t>(...) is equivalent to Ptr<t>(new T(...)): are both of the solutions (your one and my second version) free of possible memory leaks? Thanks!

Rackbox gravatar imageRackbox ( 2016-10-19 07:24:01 -0600 )edit

the danger here is not so much a memory leak, but a "dangling pointer".

consistant use of Ptr will keep you safe here (avoid "raw" pointers, whenever you can !)

berak gravatar imageberak ( 2016-10-19 07:59:37 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-10-19 05:31:04 -0600

Seen: 269 times

Last updated: Oct 19 '16