I am trying to print on which line addref and release is called.Here is code
In code below I have created on ReferenceCount class whose main functionality to increase and decrease refernce count. Referencemanager class keeps track of reference count and deletes the object once it reaches 0.
Test1 is test class .In main I am creating Test1 pointer and wrapping it with CReferenceManager class. Now during creation of CReferenceManager class AddRef is called and while destruction Release would be called.
If there is memory leak then it would be easier to detect if I can print out FILE and LINE numbers when AddRef and Release called with reference counts at that point.
If there a way that I can print FILE and LINE number from where AddRef and Release gets called. One way is that I can overwrite AddRef and Release in derived classes and prinf FILE and LINE numbers
//ReferenceCount.h
#include <string>
#include <Windows.h>
using namespace std;
class CReferenceCount
{
public:
CReferenceCount();
virtual ~CReferenceCount();
virtual void AddRef();
virtual bool Release();
private:
LONG m_ref;
};
// RefCount.cpp
//
#include "stdafx.h"
#include "ReferenceCount.h"
CReferenceCount::CReferenceCount():m_ref(0)
{
AddRef();
}
CReferenceCount::~CReferenceCount()
{
}
void CReferenceCount::AddRef()
{
InterlockedIncrement(&m_ref);
}
bool CReferenceCount::Release()
{
if (InterlockedDecrement(&m_ref) == 0)
{
delete this;
return true;
}
return false;
}
//ReferenceManager.h
#include <string>
#include <Windows.h>
using namespace std;
class CReferenceCount
{
public:
CReferenceCount();
virtual ~CReferenceCount();
virtual void AddRef();
virtual bool Release();
private:
LONG m_ref;
};
//test.cpp
#include "stdafx.h"
#include "ReferenceCount.h"
#include "RefManager.h"
#include <iostream>
using namespace std;
class Test1: public CReferenceCount
{
public:
Test1(){}
~Test1(){}
private :
int m_i;
};
void main()
{
Test1 *pTest= new Test1();
CReferenceManager<Test1> testRef(pTest);
}
Similare questions I have posted finding who creates object via smart pointer Design pattern to detect memory leaks for reference counted smart pointers
but non of the answers give right explanation to tackle this proble,
The principle of reference counting is to increase the counter when the user link to the object and to decrease when they break the link.
So you have to:
Symbolic exemple:
A a = new A();
refcount = 0, nobody use itLink<A> lnk( a );
refcount = 1obj.f( lnk );
obj stores lnk, refcount = 2obj
So, take a look at parameter passing (may do automatic copies) and at copy into foreign objects.
Good tutorials exists on that in the CORBA nebulae.
You may see also ACE or ICE, or 0MQ.
There is some way of doing this, but first let me ask you one thing. Why you want to manage references by hand and provide an opportunity for memory leaks? you can easily use
boost::intrusive_ptr
to do the job for you?( if you don't want the boost, there is no problem, see implementation ofintrusive_ptr
and implement your own class or just copy it to your own file ) and then you don't have a memory leak to search for it!!But as an answer for your question you could have 2
AddRef/Release
one for debug version and another for release and you should addAddRef
positions to an structure likestd::stack
and onRelease
pop them fromstack
and at very end you see how much references from witch positions remained in the stack! but if this is for COM implementation remember that COM may callAddRef
multiple time and then remove them at later time and thus you can't understand whichAddRef
have no correspondingRelease
.The only way is to define macros for calling AddRef and Release, since there is no way for the functions to know internally from where they are being called. So you could use something like.
Also, different compilers have different pre-defined macros; if portability is a concern, it's something you should look into when writing code like the above. MSDN reference (2003)
Given your comments below, i might offer another somewhat hackish solution. You may not be able to see where your reference is being released, but you can get more information about where it was created, and which are not being released properly.
Note this is just pseudo-code; I doubt it compiles or works out of the box!
For the projects I am involved in I had similar needs. We have our own smart-pointer template class and from time to time memory leaks appeared due to circular references.
To know which smart-pointer referencing a leaked object still is alive (2 or more), we compile the sources with a special pre-processor define which enables special debugging code in the smart-pointer implementation. You can have a look at our smart-pointer class.
In essence, each smart-pointer and reference counted object get a unique id. When we get the id for the leaked object (usually using valgrind to identify the source location of the memory allocation for the leaked object), we use our special debugging code to get all smart-pointer ids which reference the object. Then we use a configuration file where we write down the smart-pointer ids and at next application start-up, this file is read by our debugging tool which then knows for which newly created smart-pointer instance it should trigger a signal for entering the debugger. This reveals the stack trace where that smart-pointer instance was created.
Admittedly, this involves some work and might only pay off for larger projects.
Another possibility would be to record a stack trace inside your
AddRef
method at runtime. Have a look at my ctkBackTrace class to create a stack trace at runtime. It should be easy to replace the Qt specific types by standard STL types.I guess that with a bit of work and using libunwind you could probably try to get what you need (which would be a really appreciated).
http://www.nongnu.org/libunwind/docs.html
You should never allocate or release references explicitly in your own code, so storing the source file and line where references are incremented or decremented isn't going to help you at all, since those will (should!) always be inside the reference counting management code.
You did not include the source code to your CReferenceManager class, but based on your description it is a wrapper to a referenced counted object. Is this correct? The correct implementation of this CReferenceManager object should ensure that:
Also, you'd want to make the
AddRef()
andRelease()
methods in your CReferenceCount class private, and make them accessible only to the CReferenceManager class via class friendship.If you follow the above rules in your CReferenceManager class, then you can avoid leaks or other memory problems by ensuring that everybody accesses the object via a CReferenceManager wrapper allocated on the stack. In other words:
To create a new referenced counted object, passed a newly created object (with one reference) to a stack allocated CReferenceManager object. Example:
To pass the object as an argument to another function or method, always pass a CReferenceManager object by value (not by reference, and not by pointer). If you do it this way the copy constructor and the destructor will take care of maintaining the reference counts for you. Example:
If you need to stick the reference counted object in a container, then insert a CReferenceManager wrapper by value (not its pointer, and not the object's naked pointer). Example:
I believe if you strictly follow the above rules the only problems you will find are bugs in your reference counting implementation.
An example implementation that follows these rules is in this page, though that solution lacks any support for multi-threading protection.
I hope this helps!