[Proposal] Memory leak and Nullify() method

Because a lot of users have memory problem I've tried to seek why object are not deleted (some destructors were not called).
Normally when Smart pointer are smart enough to delete themselves.
When you put them in a map or a collection ref count is incremented. When Clear() method is called on these map or collection ref count is decremented etc...

But reality seems to show us lots of memory leaks. I've one suggestion for those who have memory leaks problems.
If you have lot of objects derived from Standard_Transient you can change Nullify() method and call this method at the end of your programm when you know you object are not used any more.

How ?

For Win32 :
In TKernel.dll project(FoundationClasses.dsw)

I've add commented lines to enforce deletion of object when calling .Nullify() method. Deletion is normally only obtained when reference count is equal to zero. So I decided Nullify() call would put definitively the reference counter to zero to delete the object.
It seems that in this case Nullify() can be called more than once.

Handle_Standard_Transient.hxx
void Nullify()
{
// if (entity == UndefinedHandleAddress) return;

// entity->count = 1;
// endScope decrement entity->count and check if it's = 0 then delete()
EndScope();
entity = UndefinedHandleAddress ;
}

Philippe CARRET's picture

It seems that in this case Nullify() can't (and not can) be called more than once.

I don't really know if this change in TKernel affect OCC.

Any comment of OCC expert is welcome.

Roman Lygin's picture

Philippe,

Nullify() is intended to detach a particular instance of handle (i.e. smart pointer) from a data but not to destroy the data itself.
That is, it must be valid to write:

Handle(MyPack_MyClass) aH = new MyPack_MyClass(...);
Handle(MyPack_MyClass) aH1 = aH, aH2 = aH;
//at this point counter is 3
aH.Nullify(); //counter is 2 and aH1 and aH2 keep referring to data.

In your proposal, any call to .Nullify() would destroy data and make other handles invalid (any access causes access violation).

Coming back to your original issue, I'd think that you probably meet frequent misuse of handle - a loop/cycle (i.e. handles recursively refer one to another, maybe through a chain of other handles). In this case, handles obviously cannot be automatically destroyed. You should either avoid a loop or break it at some point as soon as you're going to free memory.

Roman

P.S. I'm no longer at the Open CASCADE company but keep experimenting with Open CASCADE Technology in my spare time.

Philippe CARRET's picture

Thanks Roman,

As usual your answer is very clear. It simply give me another idea.

I'm sure people would appreciate a new method ForceDelete() (for ex) to use it only at the end of their program to ensure deletion of objects. Perhaps smart pointers are only for smart people, ForceDelete would be appreciated by "Rambo developers"

It was just to have a talk.

Philippe

Roman Lygin's picture

Hi Philippe,

Forcing memory release at the end of the program is redundant, IMHO - memory will be released by OS anyway when application exits. On the other hand, having unsafe ForceDelete() is misuse-prone and if used somewhere in run-time would destroy data.
I have never seen any smart pointer implementation (in boost.org, Qt, STL, etc) allowing explicit release. Don't think it would be relevant for OCC. Nonetheless, you might want to subclass default handles adding your method (e.g. by designing a new macro using DEFINE_STANDARD_HANDLE macro located in Standard/Standard_DefineHandle.hxx)

Good luck.
Roman

p-carret's picture

Roman,

Do you have a personnal e mail that you could send to philippe.carret@aleker.fr ?

Thanks.

Philippe