Memory leak in TopExp_Explorer

Hi Everybody !

There is a severe memory leak in TopExp_Explorer methods Init and Clear.

If the member field myTop is greater -1, resp. 0, the destructor for all TopoDS_Iterator's on the current stack is never called.

For example in BRepLib_FindSurface the Init method for the same TopExp_Explorer is called repeatedly. This has the effect that the reference counter for the first edge of a given face is continuously increasing, and its memory can never be freed.

I suspect, that one of the previous maintainance releases already incorporates a fix for this leakage. But for all non-commercial users of Open CASCADE, I give an outline of the solution to this problem.

Modify Init and Clear methods so that the destructors get called:

void TopExp_Explorer::Init(const TopoDS_Shape& S,
const TopAbs_ShapeEnum ToFind,
const TopAbs_ShapeEnum ToAvoid)
{
if(myTop >= 0)
for(int i = 0; i myStack[i].~TopoDS_Iterator();
myTop = -1;

[...]
}

void TopExp_Explorer::Clear()
{
hasMore = Standard_False;
if(myTop > 0)
for(int i = 1; i myStack[i].~TopoDS_Iterator();
myTop = 0;
}

Both forms of the TopExp_Explorer constructor have to initialize the member fields:

: myStack(0L), myTop(-1), mySizeOfStack(theStackSize)

and ReInit needs only call Init:

void TopExp_Explorer::ReInit()
{
Init(myShape,toFind,toAvoid);
}

Regards, Kris.

Win Than Aung's picture

My Code is as follow..
for(TopExp_Explorer ex(subcshape,TopAbs_FACE);ex.More();ex.Next())
{
.....
}
after getting out of the loop, the destructor for TopExp_Explorer get called. But there is not TopExp_Explorer::Clear() method in the TopExp_Explorer.cxx.
Also myTop is always -1 so
for(int i = 1; i <= myTop; ++i)
myStack[i].~TopoDS_Iterator();
the above loop never takes into action.
how come ~TopoDS_Iterator() needs to get called when myTop is greater than 0. i looked into the code and found out myTop never gets incremented.

Fabio Napodano's picture

I gave a look at the code (OCC 6.3.0); myStack is indeed actually a stack, so myTop in incremented and decremented in ::Next

at decrementation, the destructor for a single TopoDS_Iterator object in myStack is called.

when the destructor is reached, it is normal that myTop is always -1, as under normal circumstances the stack should already be empty at exit. In fact, I think that the for loop in the destructor is just a "safe measure"