分配函数作用域成员是否会导致内存泄漏

Does allocating function scope member causes memory leak?

本文关键字:内存 泄漏 是否 函数 作用域 成员 分配      更新时间:2023-10-16

我曾经分配函数范围的静态成员,因为当对这些函数的调用仅限于调试目的且内存非常有限时,它非常有用。我测试了下一个c++代码:

#include <stdio.h>
class myClass
{
public:
    myClass(int index) : m_index(index)
    {
        printf("Constructing element %dn", m_index);
    }
    ~myClass(void)
    {
        printf("Destructing element %dn", m_index);
    }
    int m_index;
};

void foo()
{
    static myClass class1(1);
    static myClass *class2 = new myClass(2);
    return;
}
void main()
{
    foo();
    return;
}

打印输出为

Constructing element 1
Constructing element 2
Destructing element 1
Press any key to continue . . .

我造成内存泄漏了吗?元素1分配在哪里?元素2分配在哪里?

这取决于如何定义"内存泄漏"。有些人将其定义为分配内存,然后不释放内存。在这种情况下,是的,您的程序存在内存泄漏,因为class2从未被删除。其他人将其定义为分配内存,然后不能释放内存,因为指向内存的最后一个剩余指针被覆盖或超出范围。在这种情况下,您的程序不会发生内存泄漏。

您的代码是否"坏"是一个意见问题。我建议不要在任何可以使用智能指针的地方使用显式new。然而,有些人建议使用静态指针,以故意防止对象被破坏,从而避免在静态对象寿命结束后访问时(即,在另一个静态对象的析构函数或atexit注册的函数调用期间)可能出现的错误。

您通过分配带有new的myClass指针(class2)而没有删除它,从而泄露了内存。在本示例的范围内,内存可以忽略不计,因为程序结束时系统会回收内存,但有人可能会说,在更大的项目中,内存可能会变得更糟糕。

至于释放它,只需在它超出范围之前将其删除,或者使用智能指针:当main完成时,它将与其他静态数据一起被销毁。

是的,这是内存泄漏,因为您没有释放已分配的内存。在这种情况下,操作系统将在程序退出时回收内存。

如果需要,可以使用c++11唯一指针使程序释放分配的内存。但是析构函数调用的顺序很难预测,如果你依赖于这个顺序,就不要走这条路。

#include <stdio.h>
#include <memory>
class myClass
{
   public:
   myClass(int index) : m_index(index)
   {
       printf("Constructing element %dn", m_index);
   }
   ~myClass(void)
   {
       printf("Destructing element %dn", m_index);
   }
   int m_index;
};
void foo2()
{
   static std::unique_ptr<myClass> class2(new myClass(2));
}
void foo()
{
   static myClass class1(1);
   return;
}
int main()
{
    foo2();
    foo();
    foo2();
    return 0;
}
  1. class1分配在静态内存中,它的析构函数在main返回后执行。

  2. class2由于new而在堆上分配,但在静态内存中也有指向它的指针,当main返回时,它会破坏指针,但不会破坏引用的对象。

第二个是一个糟糕的做法,但实际上在main返回之后,进程消耗的所有内存都应该返回到操作系统。