c++ - 静态工厂方法和静态对象内存泄漏

标签 c++ memory-leaks new-operator static-methods delete-operator

我有一个带有静态工厂构造函数的类,它返回指向所创建对象的指针。

我必须将该对象声明为命名空间内的静态对象,但我不知道如何正确删除它

class Foo
{
   public:
   Foo(int, int* );
   virtual ~Foo();
   static Foo* MyFooInitializer(int n )
   {
      int *p = new int[n];
      for (int i=0; i<n; i++)
         p[i]=i;

      Foo *ret = new Foo(n,p);
      delete p;
      return ret;
   }
   int someFooFunction(int a);
}

然后在我的命名空间中我有一个static inline 函数

namespace MyNamespace
{

    static inline void  myfunction()
    {
        static Foo  *foo1 = Foo::MyFooInitializer(10); 
        int y = somevalue();
        int x = foo1->someFooFunction(int y);
    } 
}

我这里显然有内存泄漏,因为该对象从未被删除。

重要的事实是我需要将 foo1 声明为静态的,因为一旦创建,它在所有程序中必须是相同的对象并且必须是唯一的(它跟踪一些变量)。

可能这是一个设计问题,但我不知道如何在我的程序退出时删除它,或者当我明确要删除它以重新初始化它时。

解决方案:

我这样修改了 MyFooInitializer 的主体:

   static Foo* MyFooInitializer(int n )
   {
      int *p = new int[n];
      for (int i=0; i<n; i++)
         p[i]=i;

      static Foo ret = Foo(n,p);
      delete[] p;
      return &ret;
   }

这允许我在程序终止时正确释放所有内存。 Valgrind 说所有的堆内存都被释放了!

最佳答案

这里不需要在堆上分配 Foo:

static Foo* MyFooInitializer(int x) {
    static Foo some_foo(x);
    return &some_foo;
}

该代码中没有泄漏,当您的程序结束时 Foo 将被销毁。

请注意,如果 MyFooInitializer 返回的指针实际上指向某个继承自 Foo 的类,那么您只需为静态变量使用派生类型:

static Foo* MyFooInitializer(int x) {
    static SomeFooDerived some_foo(x);
    return &some_foo;
}

编辑:由于您提供了实际的函数体,所以我的回答是有效的。你会这样做:

static Foo* MyFooInitializer(int n ) {
   // Don't know what this p is, anyway...
   int *p = new int[n];
   for (int i=0; i<n; i++)
      p[i]=i;

   static Foo ret(n,g); // what is g?
   delete[] p; // smart pointer plx
   return &ret;
}

关于c++ - 静态工厂方法和静态对象内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11137874/

相关文章:

c++ - enable_if 如何帮助选择类模板的特化?

c++ - Eclipse C++ 中的问号而不是类名

java - 我的应用程序在我的设备上占用了 250mb 内存。当我进行堆转储并对其进行分析时。它说堆大小约为 7mb

android - 在销毁 View 中将 View 可见性设置为 View.GONE

c++ - 了解 C++ 中的模板类 - new-operator 的问题

c++ - 删除模板分配的数组,可能已经分配了索引

c# - Dictionary.Contains键比较

c++ - 将制表符分隔值从文本文件读入数组

c# - 序列化 Protobuf 对象并使用 ØMQ/ZMQ 发送

Python实例删除