试图了解内存泄露的原因
Trying to understand a mem leak
我正在使用VLD(视觉泄漏检测器),它检测到一些内存泄漏。我想知道为什么这是VLD的内存泄露。可能是假阳性?
代码很简单:
CGlobalLog* CGlobalLog::m_instance=NULL; //static instance
CGlobalLog::CGlobalLog()
{
minimiumLogLevel = LOGLEVEL_INFO;
}
CGlobalLog::~CGlobalLog(void)
{
if(m_instance != NULL)
delete m_instance;
}
// this method is static
CGlobalLog& CGlobalLog::getInstance()
{
if(m_instance == NULL){
m_instance = new CGlobalLog();
}
return *m_instance;
}
其中LOGLEVEL
为enum, m_instance为CGlobalLog* CGlobalLog::m_instance
。trace是:
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 504 at 0x009B2290: 92 bytes ----------
Call Stack:
c:usersferrandirectogameprojects2008zeleste2dsrcloggloballog.cpp (26): LogSystem_v2.exe!glog::CGlobalLog::getInstance + 0x7 bytes
c:usersferrandirectogameprojects2008zeleste2dsrcloggloballog.cpp (235): LogSystem_v2.exe!glog::CGlobalLog::exposeAPI
c:usersferrandirectogameprojects2008games_and_sampleslogsystem_v2srcmain.cpp (47): LogSystem_v2.exe!main + 0xB bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (586): LogSystem_v2.exe!__tmainCRTStartup + 0x19 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (403): LogSystem_v2.exe!mainCRTStartup
0x767D339A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
0x774D9ED2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
0x774D9EA5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes
Data:
00 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD 28 23 9B 00 00 00 00 00 00 00 00 00 ....(#.. ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
B0 23 9B 00 00 00 00 00 01 00 00 00 00 00 00 00 .#...... ........
CD CD CD CD 00 CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD 00 00 00 00 0F 00 00 00 ........ ........
我找不到内存泄漏的任何原因....你能帮我一下吗?提前感谢
首先…你想象如何调用析构函数?你在任何地方调用会破坏你的对象的东西吗?
其次,在析构函数中调用delete指针将导致调用同一对象的另一个析构函数。这里有递归析构函数调用。由于它是单例类,您的调用可以简单地替换为delete this;
。你应该只将m_instance设置为NULL,这样getInstance的另一次调用将不会引用释放的内存。
解决方案吗?编写静态方法"deleteInstance",检查m_instance是否不为空,并在m_instance上调用delete,并将其设置为空。然后你应该在主函数CGlobalLog::deleteInstance();
的末尾调用i.e.。这样可以抑制内存泄漏
您可能从未真正创建过一个本地CGlobalLog
,因为您总是使用GetInstance
返回的指针,因此析构函数从未被调用。在本例中,这是一件好事,因为在程序完成之前,您确实不希望删除静态实例。您需要在程序末尾进行显式调用以删除实例成员。
我自己回应。我真丢脸!!有时候我只需要解释问题就能找到解决方法。M_instance永远不会被删除,因为析构函数是私有的,所以它是一个泄漏。
构造函数CGlobalLog::CGlobalLog()
必须将m_instance
初始化为NULL。注意,如果不是,结果是未定义的(可能是内存丢失,或者无效的delete
)。
CGlobalLog::getInstance()
中存在竞争条件,可能导致CGlobalLog
对象泄漏。假设两个线程A和B"同时"调用CGlobalLog::getInstance()
。线程A检查m_instance
,确定它不是NULL
,然后准备构造一个新的CGlobalLog
对象。但是在对new
的调用开始之前,操作系统切换到线程B。线程B检查m_instance
不是NULL
,构造一个新的CGlobalLog
对象,并将其分配给m_instance
。操作系统可能会切换到线程A。线程A,继续它离开的地方,也构造了一个新的CGlobalLog
对象并将其分配给m_instance
,从而泄漏了线程b分配的实例。
另一个可能的原因是CGlobalLog
析构函数删除了m_instance
,如果它不是NULL
。当被删除的对象是m_instance
所指向的CGlobalLog
对象时,则该对象被双重删除。
- 了解内存序列和标准::memory_order_relaxed
- 准确了解对象在内存中的映射方式
- 了解 Linux 虚拟内存:valgrind 的 massif 输出显示了有和没有 --pages-as-heap 的主要差异
- 我刚刚了解了C++中的动态内存分配
- 关于内存泄漏,我有什么不了解的
- 不了解C 内存对齐
- 了解标准::原子内存屏障
- 了解循环缓冲区实现的内存分配性质
- 了解Microsoft的内存泄漏检测输出
- 通过动态内存分配了解2D数组
- 基本指针如何能够在派生的类实例中了解基本成员的内存位置
- 了解堆栈,堆和内存管理
- 了解SSE的内部函数如何使用内存
- 了解 C++ 中动态内存分配的使用
- CUDA - 了解线程的并行执行(扭曲)和合并的内存访问
- 了解内存分配
- 了解字符数组内存分配
- 了解我有多少内存可用于一个动态向量c++
- 了解内存分配的工作原理(LLVM)
- 试图了解内存泄露的原因