检测引用计数对象中的内存泄漏 [英] Detecting memory leak in reference counted objects

查看:200
本文介绍了检测引用计数对象中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图打印调用addref和release的行。这是代码



在下面的代码中我创建了ReferenceCount类,其主要功能增加和减少参考计数。
Referencemanager类保持跟踪引用计数,并在对象达到0时删除该对象。



Test1是测试类。在我创建Test1指针并包装它与CReferenceManager类。现在在CReferenceManager类的创建过程中,AddRef被调用,而destroy将被调用。



如果有内存泄漏,那么更容易检测是否可以打印出FILE



如果有一种方法可以打印FILE和LINE号码,从这里AddRef和Release被调用。一种方法是,我可以覆盖AddRef和Release在派生类和原始的FILE和LINE数字

  // 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
//

#includestdafx.h
#includeReferenceCount.h


CReferenceCount :: CReferenceCount():m_ref(0)
{
AddRef();

}

CReferenceCount ::〜CReferenceCount()
{
}

void CReferenceCount :: AddRef b $ b {
InterlockedIncrement(& m_ref);
}

bool CReferenceCount :: Release()
{
if(InterlockedDecrement(& m_ref)== 0)
{
删除此;
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
#includestdafx.h
#includeReferenceCount.h
#includeRefManager.h
#include< iostream>
using namespace std;

class Test1:public CReferenceCount
{
public:
Test1(){}
〜Test1(){}
$ b b private:
int m_i;
};

void main()
{
Test1 * pTest = new Test1();
CReferenceManager< Test1> testRef(pTest);

}

Similare问题我已发布
查找谁通过智能指针创建对象
http:// stackoverflow。 com / questions / 12805366 / design-pattern-to-detect-memory-leaks-for-reference-counted-smart-pointers



但是没有答案给出正确的解释解决这个问题,

解决方案

唯一的方法是定义宏调用AddRef和Release,因为没有办法函数从内部知道他们被调用。所以你可以使用像。

  #define RELEASE(obj)cout< __LINE__<< :<< __FILE__<< endl (obj).Release(); 

此外,不同的编译器有不同的预定义宏;如果可移植性是一个关注,这是你应该看看当编写代码像上面的东西。 MSDN参考(2003) p>

根据您的意见,我可能会提供另一个有点黑客的解决方案。您可能无法看到您的参考资料在哪里发布,但您可以获得有关其创建位置和哪些未正确发布的详细信息。

  template< typename T> 
struct CReferenceManager
{
CReferenceManager(const T& _obj,const string& _file,int _line):mObj(_obj),mFile(_file),mLine(_line)
{
cout<< 构建自< _file<< :<< _line<< endl
CReferenceManager :: sObjects [make_pair(mFile,mLine)] ++;
mObj.addRef();
}

〜CReferenceManager()
{
cout< Destructing object created at<< mFile< :<< mL < endl
CReferenceManager :: sObjects [make_pair(mFile,mLine)] - ;
mObj.Release();
}

静态映射< pair< string,int> int> sObjects;
string mFile;
int mline;
T obj;
}

int main()
{
...
//在返回之前循环通过sObjects,注意任何未释放的条目
return 0;
}

注意这只是伪代码;我怀疑它编译或工作开箱!


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 http://stackoverflow.com/questions/12805366/design-pattern-to-detect-memory-leaks-for-reference-counted-smart-pointers

but non of the answers give right explanation to tackle this proble,

解决方案

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.

#define RELEASE(obj) cout << __LINE__ << ":" << __FILE__ << endl; (obj).Release();

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.

template <typename T>
struct CReferenceManager
{
    CReferenceManager(const T & _obj, const string & _file, int _line) : mObj(_obj), mFile(_file), mLine(_line)
    {
        cout << "Constructing from " << _file << ":" << _line << endl;
        CReferenceManager::sObjects[make_pair(mFile, mLine)]++;
        mObj.addRef();
    }

    ~CReferenceManager()
    {
        cout << "Destructing object created at " << mFile << ":" << mLine << endl;
        CReferenceManager::sObjects[make_pair(mFile, mLine)]--;
        mObj.Release();
    }

    static map<pair<string, int>, int> sObjects;
    string mFile;
    int mLine;
    T obj;
}

int main()
{
...
    // Cycle through sObjects before return, note any unreleased entries
    return 0;
}

Note this is just pseudo-code; I doubt it compiles or works out of the box!

这篇关于检测引用计数对象中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆