In the book C#12 In A Nutshell, authors write this code:
UnsafeClass a = new UnsafeClass ("Christian Troy");
unsafe struct UnsafeUnicodeString
{
public short Length;
public fixed byte Buffer[30];
}
unsafe class UnsafeClass
{
UnsafeUnicodeString uus;
public UnsafeClass (string s)
{
uus.Length = (short)s.Length;
fixed (byte* p = uus.Buffer)
for (int i = 0; i < s.Length; i++)
p[i] = (byte) s[i];
}
}
They then mention
The fixed keyword is also used in this example to pin the object on
the heap that contains the buffer (which will be the instance of
UnsafeClass)
I’m not sure I understand what they mean / what they are talking about. If they’re talking about a
, why would a
need to be pinned. If they’re talking about uus
, why would they say “pin the object on the heap”, uus
should be on the stack right? (only value types)
Or maybe they’re talking about p
? But p
is on the stack if I understand correctly?
4
When we use fixed
in this way, the buffer is pinned wherever it is; this could potentially be on the stack (in which case nothing actually changes, although the steps are still observed), but in this case uus.Buffer
refers to a field of an object. What we end up with is an special local that is an “interior pointer” to an address inside an object that is on the heap (the UnsafeClass
instance). The UnsafeUnicodeString
is not on the stack at any point here – just the address of the field (on a specific object) is loaded.
It is this special locals that indirectly pins the object; the GC is required to locate all of these special locals on the stack (when activating the GC), and ensure that the wider object gets treated as pinned.
The object (the same object that a
points to) needs to be pinned be ause that’s where the data is – as a field inside that object. If it wasn’t pinned, the pointer p
would be pointing to the wrong location – this is na unmanaged pointer and unmanaged pointers are not adjusted by the GC during moves (the point being that you’re meant to help the GC not move them, which is what we’re doing here).
2