我創建了一個整潔的小功能,刪除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,但是當它們返回時,跟蹤引用似乎沒有更新。從控制檯輸出中可以看到,它不僅僅是一個調試器問題。
我不明白的是爲什麼
在第一種情況下,使用'list'而不是'enumerable'只是在代碼中出現錯字或實際錯誤? – svick 2012-02-16 16:31:18
錯字在把一些嚴重命名變量 - 現在固定;-) – 2012-02-16 16:33:15
你能不能告訴我們,調用該函數的代碼?換句話說,告訴我們你期望什麼是'nullptr',但不是。 – svick 2012-02-16 16:39:35