2013-10-15 41 views
-1

我有用/clr編譯的C++/CLI庫。庫中的內存泄漏

ref class MyClass 
{ 
private: 
    array<int>^ d; 
public: 
    MyClass() 
    { 

     int size=10000000; 
     d=gcnew array<int>(size); 
     for(int x=0;x<size;x++) 
     { 
      d[x]=x; 
     }; 
    }; 
    ~MyClass() 
    { 

     MessageBox::Show(gcnew String(L"Disposed")); 
    }; 
    protected: 
    !MyClass() 
    { 
    MessageBox::Show(gcnew String(L"Finalized")); 
    }; 
}; 

static MyClass^ Test() 
{    
    MyClass^ mc = gcnew MyClass(); 
     //msclr::auto_handle<MyClass^> mc = gcnew MyClass();//this shows error 
     //msclr::auto_handle<MyClass> mc = gcnew MyClass();//this either shows error 
     //due to return type of function Test() 


    return mc; 
}; 

當我使用這種方法,它超出了範圍它應該顯示「Disposed」並釋放內存。

private void button1_Click(object sender, EventArgs e) 
{ 
     MyDll.MyClass mc= MyDll.Test(); 
} 

不幸的是,它並沒有這樣做。只有通過執行Finalizer,應用程序退出後,內存纔會釋放。如何正確釋放這個內存?

回答

0

對於使用new或gcnew分配的指針,C++或C++/cli沒有自動刪除。你必須調用delete,或者在你的情況下(我假設'mc'是在C#程序集中)mc.Dispose()。如果沒有明確的處置,則由GC決定完成。

注意:在沒有調用delete的情況下調用new(我排除gcnew,這裏)是內存泄漏。

+0

如何配置陣列^obj = gcnew array (size);'? – maszynaz

+0

爲什麼'dispose後的GC.Collect();'命令不會自動調用? – maszynaz

+0

它是.NET:處理事情你必須調用Dispose,否則垃圾收集器在某個時間點完成分配(以某種方式平衡性能和內存管理)。要處理一個對象數組,你必須遍歷數組並處理每個元素。 –

2

您可以在C++/CLI中使用堆棧語義來讓編譯器自動創建和處理該對象。非常類似於本地C++:

static void Test() {    
    MyClass mc; 
} 

注意失蹤^帽子和需要返回一個釋放的對象。在原來的片段它必須由調用明確完成:

static void RunTest() { 
    MyClass^ obj = MyClass::Test(); 
    delete obj; 
} 

最後但並非最不重要的,你注意,在做這個根本沒有任何意義。只有釋放非託管資源才需要析構函數和終結器。垃圾收集器已經自動釋放MyClass對象。不需要幫助,也不應該嘗試幫助。