anand
anand

Reputation: 11329

Design pattern to detect memory leaks for reference counted smart pointers

We have our own smart pointers class which is reference counted using basic AddRef and Release.

While debugging I am able to see lot of objects not being released properly. I can see which objects not being released but its hard to find out from which place they get allocated.

Is there any good design pattern to address this problem?

I have put debug statements and ADDREF and RELEASE and I can see reference count when release is called . In some cases its more than 1, that means pointer is not deleted.

If I start putting breakpoints on shared_ptr const , then it will called hundred of times and its difficult to pinpoint memory leak.

It looks like some cyclic references getting created which is causing these leaks.

Upvotes: 0

Views: 776

Answers (2)

John Dibling
John Dibling

Reputation: 101476

Years ago, before auto_ptr, I wrote my own smart pointer class which we used in our codebase extensively. Of course, it was chock full of bugs.

I had exactly the same problem. While I can't show you the actual code I used to identify the call sites where resource leaks originated (because the code no longer exists), I can tell you what I did.

The first thing was I wrote a #define macro >SHUDDER<, similar to the one I outline here, which I could use in place of new to allocate my objects. The macro sent additional parameters to the smart pointer, indicating file & line number of the call site. The smart pointer would retain this.

Then I replaced the global new with my macro when I uttered a magical incantation of #defines turning this functionality on. Obviously, this should be disabled in all Releasse builds, and only used in Debug builds when you're actually debugging this.

Then I let my program run until I got to a point where I wanted to see all the call sites. I'd execute a dump_call_sites() method on the smart pointer there, which dumped the static vector of call site strings to the stdout. Problem hence found, I'd revert all those magical incantations to turn off all this hokus pokus.

This is truly hack-n-slash codiing. It' far from elegant, and it introduces it's own set of problems. But along with printf debugging, it has its place. If you don't want to or can't go to the effort of loading up your Rational Purify or Bounds Checker type product, this could help you quickly identify where your leaks are coming from.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258618

Don't use design patterns for this. Don't add code bloat just to detect leaks.

Use a memory tool. Valgrind comes to mind, and a number of commercial ones for Windows.

Also...

I can see which objects not being released but its hard to find out from which place they get allocated.

Why? Set a breakpoint in the constructor of the object. Or use the standard pointers instead (std::shared_ptr, std::unique_ptr).

As per your edit:

I have put debug statements and ADDREF and RELEASE and I can see reference count when release is called . In some cases its more than 1, that means pointer is not deleted.

Are you taking into account copy elision (RVO/NRVO)? This seems more likely to be the cause.

Upvotes: 2

Related Questions