作成されたオブジェクトへのポインターを返す静的ファクトリコンストラクターを持つクラスがあります。
オブジェクトを名前空間内の静的オブジェクトとして宣言する必要がありますが、正しく削除する方法がわかりません
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は、すべてのヒープメモリが解放されたと言います。