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

3

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

#include <stdio.h>

class myClass
{
public:
    myClass(int index) : m_index(index)
    {
        printf("Constructing element %d\n", m_index);
    }

    ~myClass(void)
    {
        printf("Destructing element %d\n", 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分配在哪里?

4个回答

6
这取决于如何定义"内存泄漏"。有些人认为这意味着你分配了内存,然后没有将其释放。在这种情况下,是的,你的程序存在内存泄漏问题,因为`class2`从未被删除。其他人则认为,这意味着你分配了内存,但由于指向该内存的最后一个指针被覆盖或超出范围,无法释放它。在这种情况下,你的程序就没有内存泄漏。
你的代码是否"不好"是一个主观的问题。我建议在可以使用智能指针的任何地方都不要使用显式的`new`。然而,有些人建议使用静态指针来故意避免对象被销毁,以避免在另一个静态对象的析构函数或通过`atexit`注册的函数调用期间访问静态对象时可能会发生的错误。

非常棒的回答。致敬 :). - The Marlboro Man
@Brian..不错!您能否提供一些链接以更好地理解这个语句“有些人建议使用静态指针,以有意防止对象被销毁”? - Saurav Sahu
@SauravSahu 请参考 https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables 。虽然我不是赞同 Google C++ 风格指南。 - Brian Bi

1
你通过使用new分配一个myClass指针(class2)并没有将其删除,导致了内存泄漏。在这个例子的范围内,这个问题可以忽略不计,因为当程序结束时系统会回收内存,但是在更大的项目中可能会变得更糟糕。
要释放它,只需在超出作用域之前删除它或使用智能指针:当main函数结束时,它将与其他静态数据一起被销毁。

1

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

如果你希望程序能够释放已分配的内存,可以使用C++11的unique pointer,但析构函数的调用顺序很难预测,如果你依赖于顺序,请不要选择这条路。

#include <stdio.h>
#include <memory>

class myClass
{
   public:
   myClass(int index) : m_index(index)
   {
       printf("Constructing element %d\n", m_index);
   }

   ~myClass(void)
   {
       printf("Destructing element %d\n", 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;
}

0
  1. class1 分配在静态内存中,它的析构函数在 main 函数返回后执行。

  2. class2 由于使用了 new 操作符而分配在堆上,但指向它的指针也在静态内存中。当 main 函数返回时,它会销毁指针但不会销毁引用对象。

第二种情况是一种不好的实践,但实际上,在 main 函数返回后,进程消耗的所有内存都应该归还给操作系统。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接