Currently, I have this code:
class SO
{
public SO()
{
var ptrManager = new PointerManager();
int i = 1;
ptrManager.SavePointer(ref i);
Console.WriteLine(i); // prints 1
i = 2; //change value to 2 within the current scope
Console.WriteLine(i); // prints 2
ptrManager.SetValue(3); // change value to 3 in another (unsafe) scope
Console.WriteLine(i); // prints 3
}
}
unsafe class PointerManager
{
private int* ptr;
public void SavePointer(ref int i)
{
fixed (int* p = &i)
{
ptr = p;
}
}
public void SetValue(int i)
{
*ptr = i;
}
}
First, I tell the PointerManager
to create a pointer pointing to my int i
.
This way, later, i'll be able to tell the PointerManager
to change the value of i
, without having to pass i
in again.
This seems to work well so far. However, I've read that if the GC decides to move i
around in memory, then my pointer ptr
will become invalid, and subsequent calls to SetValue
will have unpredictable behaviour.
So, how do I prevent GC from moving i
around? Or, alternatively, is there a better way of accomplishing my goal?
I've also been told that simply adding GCHandle.Alloc(i, GCHandleType.Pinned);
will work, but that doesn't seem right...
Edit: To be more specific, GCHandle.Alloc
would be called at the beginning of the SavePointer
method.
manager.Rollback
, restoring the values of your variables.