2013-10-15 40 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对象。不需要帮助,也不应该尝试帮助。