MSDN говорит, что
Вы также можете использовать GCHandle для создания закрепленного объекта, который возвращает адрес памяти, чтобы предотвратить перемещение объекта в памяти сборщиком мусора.
Когдаhandle выходит за рамки видимости, вы должны явно освободить его, вызвав метод Free;в противном случае возможны утечки памяти.Когда вы освобождаете закрепленный дескриптор, связанный объект будет откреплен и станет пригодным для сбора мусора, если на него нет других ссылок.
Так что, если неподкрепленный, или обычный GCHandle, был создан дляобъект управляемого класса с именем fooObj,
GCHandle gch = GCHandle::Alloc(fooObj, GCHandleType::Normal);
нужно ли его освобождать с помощью Free ()?
gch.Free();
Или GC освобождает его, когда он не требуется?
* 1016Причина, по которой я не хочу освобождать его, заключается в том, что в следующем коде мне нужно, чтобы paramsArgVPtr и gch1 продолжали ссылаться на объект fooObj даже после выделения и освобождения дополнительных GCHandles, таких как gch2.Но похоже, что после освобождения gch2 связанный объект открепляется, несмотря на то, что gch1 все еще ссылается на него.В любом случае gch1 теряет доступ к объекту.
#include "pch.h"
#include <iostream>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
ref class Foo // Required to be a managed ref class
{
private:
int a = 0;
};
int main()
{
Foo ^ fooObj = gcnew Foo();
// Get a void pointer that can access the object
GCHandle gch1 = GCHandle::Alloc(fooObj, GCHandleType::Normal);
void * paramsArgVPtr = GCHandle::ToIntPtr(gch1).ToPointer();
// This would happen in an external non-member function that accepts a void * argument paramsArgVPtr
// But I'm putting it here for a minimal example.
GCHandle gch2 = GCHandle::FromIntPtr(IntPtr(paramsArgVPtr));
Foo ^ fooObjCopy = safe_cast<Foo ^>(gch2.Target);
gch2.Free();
// Check to see if the object is still accessible through gch1
if (gch1.Target == nullptr)
{
cout << "gch1 points to a null pointer after freeing gch2" << endl;
}
else
{
cout << "gch1 can still access the object after freeing gch2" << endl;
}
gch1.Free();
}