log4cpp 内存泄漏的一个出现情况

一直用log4cpp的library方式(非DLL)连接到自己的程序中(可从我的资源中下载)

最近发现一个内存泄漏的问题,感觉很奇怪:

  从主程序中传入一个Category对象的指针pLog到类实例Ca中,Ca对象存在于独立的DLL中并且用 LoadLibrary(..)的方式装载到主程序。

  当DLL被装载后,Ca开启一个线程Ta并把pLog传入到此线程Ta中。

  主程序与Ca对象全部以static library的方式引用了 log4cpp。

  OK,出现内存泄漏的情况是:只要线程Ta中调用了日志的任何函数(debug,info...),就会出现'泄漏'(当然这个不一定称为泄漏,请看我以前的文章)。


查了这个问题的原因,也大概看了一下代码。终于找到了问题的所在:

当log4cpp以 static library 的形式被调用时,任何调用的对象都会 'Copy'一份到自己的‘空间’里。所以,Ca所在的DLL会拥有一份,主程序也会有一份,而每一份log4cpp的COPY都会生成一个    

 namespace {
        threading::ThreadLocalDataHolder<NDC> _nDC;
    }

实例。(请参看:NDC.CPP 27行)


_nDC对象的用处看其定义就应该明白大概的了! ---- 与线程有关!(具体请大家自己看代码吧 :( )


当在 Ta 中调用时,使用的_nDC 是主线程是实例!

在线程 Ta 的最后调用 log4cpp::NDC::clearCurrentThreadNDC() 时,使用的_nDC则是当前Dll内的一个实例(请看我的另一文章http://blog.csdn.net/ani/article/details/6372025),根据不同的实例对查找资源,当然就找不到要删除的内存了!


你会发现:那此时不是有两个一模一样的全局对象了! 名字也相同?! 

是的,这是允许的!大家可以去查询一下相关的资料!(http://stackoverflow.com/questions/2928957/is-it-possible-to-declare-multiple-static-variable-with-same-name-in-a-single-c-f)


所以,解决的方案是:把 log4cpp 的 static library 的使用方式换成 DLL 的方式!保证在一个 process 中,只有一个 _nDC 实例存在!

(我已经编译好了一份,大家可以在这里下载:http://download.csdn.net/detail/Ani/3648356)


有问题请指正!

欢迎转载!

Ani
发布了83 篇原创文章 · 获赞 11 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Ani/article/details/6835382