静态工厂方法和静态对象内存泄漏
Static factory methods and static objects memory leaks
我有一个带有静态工厂构造函数的类,该构造函数返回指向所创建对象的指针。
我必须将对象声明为命名空间中的静态对象,但我不知道如何正确删除它
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;
}
这使我可以在程序终止时正确释放所有内存。瓦尔格林德说所有的堆内存都被释放了!
这里不需要在堆上分配该 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;
}
怎么样
static inline void myfunction()
{
static std::unique_ptr<Foo> foo1(Foo::MyFooInitializer(10));
int y = somevalue();
int x = foo1->someFooFunction(int y);
}
如果你绝对需要动态创建 foo1,那么编写一个额外的类,并按值使其成为静态/全局的。然后使用它的析构函数删除对象。
class MasterControlClass
{
public:
Foo* foo1;
MasterControl(){foo1 = NULL;}
~MasterControl(){delete(foo1), foo1 = NULL;}
};
static inline void myfunction()
{
static MasterControlClass mcp;
mcp.foo1 = Foo::MyFooInitializer(10);
}
这样,当您的程序关闭时,mcp desctructor 将被调用并执行清理。如果要重新初始化,则必须在每次分配时删除foo1,只需添加
if(mcp.foo1)
{
delete mcp.foo1;
mcp.foo1= NULL;
}
或者更好的是,将其移至mcp方法。
相关文章:
- 我们可以删除链表中静态内存中的节点吗
- 添加静态constexpr成员是否会更改结构/类的内存映射
- 将静态内存更改为动态C++
- 我应该在这个程序中使用静态内存分配还是动态内存分配
- C++ 中对象数组的静态内存分配
- 在声明节点创建链接列表时,为什么静态内存分配不起作用
- 使用新的位置来创建静态常量指针,指向静态内存缓冲区
- 静态内存中的数组的大小可以在运行时更改C++?怎么来了
- 使用MPI和C 发送静态内存2D数组
- 确定是否将对象分配在静态内存块中(还是如何避免数据竞赛条件)
- C/C++ 动态或静态内存分配
- 静态内存地址是否随不同的计算机而变化
- 动态内存、堆栈内存和静态内存与c++中的区别
- 在释放静态内存之前已完成卸载DLL
- 静态内存使用的分层概述
- 静态内存实例中的字符串计数
- C++浮点常量总是存储在静态内存中吗
- 动态和静态内存分配
- 每个类类型的静态内存池对象
- 静态内存分配中的浅拷贝构造函数问题