0

我有一個類具有靜態工廠構造函數返回一個指向創建的對象。靜態工廠方法和靜態對象的內存泄漏

我必須聲明的對象作爲命名空間中的靜態對象,但我不知道如何刪除它正確

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被聲明爲靜態的,因爲一旦創建了所有的程序中,它必須是同一個對象,並且必須是唯一的(它會跟蹤一些變量)。

也許這是一個設計問題,但我不知道如何在我的程序退出或當我明確地想刪除它重新初始化它刪除。

SOLUTION:

我修改的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說所有的堆內存都被釋放了!

+0

你沒有在任何地方使用'new()',那麼你爲什麼認爲你有內存泄漏? –

+0

@Als我敢打賭,'MyFooInitializer'中有一個新的。 –

+1

@LuchianGrigore:它很可能是一個本地'靜態'實例,它在整個程序生命週期中始終保持活動狀態。如果不是,只需將'new'替換爲一個,然後就沒有泄漏:) –

回答

4

沒有必要在這裏堆中分配是富:

static Foo* MyFooInitializer(int x) { 
    static Foo some_foo(x); 
    return &some_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; 
} 
+0

切片在哪裏?我在我的例子中看到一個指針。 – mfontanini

+0

哦,我的壞.4321 –

+0

因此,我們來到單身模式。 –

0

如何

static inline void myfunction() 
{ 
    static std::unique_ptr<Foo> foo1(Foo::MyFooInitializer(10)); 
    int y = somevalue(); 
    int x = foo1->someFooFunction(int y); 
} 
+0

我沒有找到unique_ptr(我在寫C++ O3標準)。我用g ++ - 4.4編寫我的代碼,它必須在g ++> = 4.0和windows上編譯,似乎unique_ptr不在標準頭文件中。 我在哪裏可以找到它? (我不能使用提升)。 – linello

+0

@linello從不介意:) –

0

如果您確實需要動態地創建了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將被調用並進行清理。 如果你想重新初始化,然後OFC你必須在每一個分配刪除foo1,只需添加

if(mcp.foo1) 
{ 
    delete mcp.foo1; 
    mcp.foo1= NULL; 
} 

甚至更​​好,將其移動到MCP的方法。