今天在实现一个文件访问的组件时,发现始终有内存泄漏;跟踪后发现,是两个 COM 对象互相引用导致计数器无法归零导致的。
大致情况是: CDGFile 为主对象;CDGFileSegment 为子对象;他们之间互相保留指针,因此都作了引用计数,现在,使用者通过智能指针各保留了一份引用,如下:
CDGFilePtr ptrFile;
CDGFileSegment ptrSegment;
此时,ptrFile,ptrSegment 中的计数器均为 2 :因为智能指针各保留了一份;对象之间也各保留了一份。当退出当前函数时,智能指针先后析构,指针数先后减 1 ;但内部互相引用的计数仍然存在,因此导致了内存泄漏!
解决方法:当需要互相引用时,应该根据逻辑上的层次,仅对一方作引用计数;
比如本例的解决方案:
1、CDGFile 是 CDGFileSegment 的父对象,因此 CDGFileSegment 中保留的 CDGFile 不应该作引用计数,程序逻辑应该自己控制父对象一直有效;
2、因为父对象 CDGFile 中保留有 CDGFileSegment 的指针,因此,CDGFile 在销毁前,应该将 CDGFileSegment 中保留的 CDGFile 指针置为空,以标志父对象已失效!
3、在对象结束生命期之前,清除引用。例如,可以增加 Final() 成员函数,在该函数中清除对其他对象的引用。
以下是网上找到的相关资料,做个记号:
http://topic.csdn.net/u/20090705/04/de76dce2-031d-4566-b1b5-84380558328e.html