Reputation: 11329
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
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
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
).
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