【问题标题】:could static array cause memory leak in this case?在这种情况下,静态数组会导致内存泄漏吗?
【发布时间】:2013-11-15 15:27:20
【问题描述】:

//CVMI.cpp

static char* std1[] = {"a","b","c"};
static char* std2[] = {"1","2","3"};

CVMI::CVMI(HWND p)
{
  //Does nothing.
}

//CVMI.h

const int   cMaxIPAddr = 100;
class CVMI : public VMIListener
{
 public:
CVMI(HWND p); 
    VMI vmi;
bool    bOpen;
    char                sVoceraIPAddr[cMaxIPAddr + 1];
long                iMessageID; 
};

以上是我在线程中使用并运行 for 循环的类的代码。如果将以下三行放在那个 for 循环中,那么我注意到我的记忆会飞速发展。

m_pVMI = new CVMI(m_hNotifyWnd);
delete m_pVMI;
m_pVMI = NULL;

我在这里做错了什么?我虽然我的删除每次都会处理内存分配。还是我必须专门释放析构函数〜CVMI()中的所有资源? .这是我第一次尝试解决内存泄漏问题,作为一个 C++ 初学者并没有让它变得更容易。

编辑:

 class VMI_API VMIListener : public Listener
 {                                                                                      

 public:

// Message acknowledgement.  iAckCode is one of AC codes.
virtual void    HandleAck(long iMessageID, char* sLoginID, int iAckCode) = 0;   
virtual void    HandleResponse(long iMessageID, char* sLoginID, char* sResponse) = 0;
virtual void    HandleConnectionFailed(void) = 0;
  };

【问题讨论】:

  • VMIListener 有虚拟析构函数吗?
  • 看不到,我只是粘贴在VMI监听器的基本部分。
  • @Fylix VMIListenerListener 都需要 virtual destructors
  • 您没有显示回答此问题所需的代码。什么是m_pVMI,它是如何声明的?
  • 顺便说一句,您是如何检测到内存泄漏的?您使用的是哪个 IDE?如果您使用的是 Visual Studio,则在调试模式下运行它,当程序退出时,调试窗口中是否有消息,例如“检测到内存泄漏!转储对象 ->.......”?

标签: c++ memory-leaks


【解决方案1】:

你需要检查几个地方:

  1. 使用“CVMI”的调用者。

    正如你所描述的,没有内存泄漏,因为你有“删除”

    m_pVMI = new CVMI(m_hNotifyWnd);
    delete m_pVMI;
    m_pVMI = NULL;
    
  2. “CVMI”类

    根据您的代码,您“新建”并立即“删除”并且您的构造函数什么都不做,那么这不是内存泄漏的地方。

  3. 唯一可疑的地方是“VMIListener”或基类“Listener”的构造函数(如果那个也有基类,请检查基类...),也许它分配给内存变量如: m_foo = new CFoo();在构造函数中;但是,如果您没有为“VMIListener”(或 Listener 或超类)定义析构函数,则可以保证内存泄漏。

【讨论】:

    【解决方案2】:

    std1std2,您的静态数组,不会导致您的内存泄漏。它们甚至没有在上面的代码中使用,所以不清楚你的标题来自哪里。至于OP cmets中提到的虚析构函数,完全取决于Listener的实现是什么,因为VMIListenerCVMI都不是动态分配内存的。

    【讨论】:

    • 实际上他们正在做动态分配,因为他们正在使用虚拟方法(为方法分配插槽请参阅我上面评论中的链接),重要的问题是如何声明 m_pVMI,如果它已声明作为CVMI,那么他是安全的,如果不是……那么这是未定义的行为
    • 使用虚拟方法如何暗示动态分配?一个类可以有虚方法,而该类没有进行任何动态分配的成员。虚拟表与潜在的内存泄漏无关。
    • 它与潜在的内存泄漏有很大关系,如果没有虚拟析构函数,运行时不知道释放派生类的 vtable 或它们可能已经完成的任何相关分配。它只会释放 vtable 的开销和基类的任何相关内存。我链接到的问题很清楚。这就是为什么通过没有虚析构函数的基类接口删除派生类是未定义的行为。
    • 什么是“vtable 的支出”?鉴于他发布的代码,他没有做任何他自己的动态分配,因为他的成员类型是微不足道的,除了VMI。根据该类的作用,是的,如果VMI 进行动态分配,将会有一些泄漏。
    • 看看gotw.ca/publications/mill18.htmEffective C++ 他们对细节的解释比我做得好得多。让它足够是未定义的行为并且非常危险。还有stackoverflow.com/questions/408196/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 2011-02-15
    相关资源
    最近更新 更多