我创建了一个简洁的小函数来删除一个 ienumerable 及其内容(以填补我最近发现的内存泄漏):
generic<typename T>
void CollectionHelpers::DeleteEnumerable(IEnumerable<T>^% enumerable)
{
if(enumerable != nullptr)
{
for each( T obj in enumerable)
{
delete obj;
}
delete enumerable;
enumerable = nullptr;
}
}
DeleteEnumerable
...但是由于某种原因,当我使用调试器进行跟踪时,当我从函数返回时,列表似乎仍然指向一些内存。
我认为通过作为跟踪参考传入它应该修改我传入的句柄?我在这里错过了什么?
编辑:一个更彻底的测试示例......
这是一个稍微更新的处理程序:
using namespace GenericCollections;
using namespace System::Collections::Generic;
using namespace System;
generic<typename T>
void CollectionHelpers::DeleteEnumerable(IEnumerable<T>^% enumerable)
{
if(enumerable != nullptr)
{
for each( T obj in enumerable )
{
Console::WriteLine("Disposing of object");
delete obj;
}
Console::WriteLine("Disposing of enumerable");
delete enumerable;
enumerable = nullptr;
}
if( enumerable == nullptr )
{
Console::WriteLine("enumerable tracking reference is nullptr");
}
else
{
Console::WriteLine("enumerable tracking reference is NOT nullptr");
}
}
这是调用处理器的代码的精简示例:
using namespace System;
using namespace GenericCollections;
using namespace System::Collections::Generic;
ref class MyClass
{
private:
int* m_myBuf;
public:
MyClass()
{
m_myBuf = new int[100];
Console::WriteLine("MyClass::MyClass()");
}
~MyClass()
{
delete [] m_myBuf;
m_myBuf = NULL;
Console::WriteLine("MyClass::~MyClass()");
}
};
int main(array<System::String ^> ^args)
{
List<MyClass^>^ myList = gcnew List<MyClass^>;
myList->Add(gcnew MyClass());
myList->Add(gcnew MyClass());
myList->Add(gcnew MyClass());
CollectionHelpers::DeleteEnumerable(myList);
if(myList == nullptr)
{
Console::WriteLine("Original list is disposed of");
}
else
{
Console::WriteLine(String::Format("Original list still referenced: {0}", myList));
}
return 0;
}
...这是输出:
MyClass::MyClass()
MyClass::MyClass()
MyClass::MyClass()
Disposing of object
MyClass::~MyClass()
Disposing of object
MyClass::~MyClass()
Disposing of object
MyClass::~MyClass()
Disposing of enumerable
enumerable tracking reference is nullptr
Original list still referenced: System.Collections.Generic.List`1[MyClass]
老实说,我并不担心删除可枚举的作品是否是其中包含的需要被杀死的对象。我们到处使用这些列表,但我们的系统内存不足,因为它们没有被足够快地清理干净。
更糟糕的是,我们依赖该DeleteEnumerable
函数将列表跟踪引用设置为 nullptr,但是当它们被传回时,跟踪引用似乎没有更新。从控制台输出中可以看出,这不仅仅是调试器问题。
我不明白的是为什么