我在尝试使用类型访问结构体静态字段的值时遇到了这种行为uint*
调试时,监视窗口显示静态字段StaticBitMask
的值为零,但实际上(并且如预期的那样)它是一个有效的指针,并且Console.WriteLine()
打印它,如下面的控制台输出所示:
Pointers:
-----------------
Static bitmask pointer: 0x706790
Instance bitmask pointer: 0x708A20
Values:
-----------------
Static bitmask pointer val: 0xFFFFFFFF
Instance bitmask pointer val: 0xFFFFFFFF
使用固定实例字段不会观察到这种不一致的行为。对于这些,可以在监视窗口中看到实际值并打印出来。
为什么会发生这种情况?顺便说一句,我知道这不是一个令人惊叹的节目,但为什么,有人想知道。
另外,结构体中具有指针类型的静态字段会产生什么后果?因为它不能被标记为fixed
,是否有可能随时移动购买GC?
这是源代码,您可以直接作为控制台应用程序运行来重现问题。
Thanks.
using System;
using System.Runtime.InteropServices;
public unsafe struct UIntBitMask
{
private static int uintNumberOfBits = sizeof(uint) * 0x8;
public static uint* StaticBitMask;
public fixed uint InstanceBitMask[1024]; // uintNumberOfBits * uintNumberOfBits = 32 * 32 = 1024
public UIntBitMask(bool fillBitMask)
{
GetUnmanagedBitMask();
}
static UIntBitMask()
{
IntPtr pointer = Marshal.AllocHGlobal(uintNumberOfBits * uintNumberOfBits * sizeof(uint));
StaticBitMask = (uint*)pointer.ToPointer();
for (int i = 0; i < uintNumberOfBits; i++)
for (int j = 0; j < uintNumberOfBits; j++)
((uint*)&StaticBitMask[i])[j] = ((uint.MaxValue >> (uintNumberOfBits - j)) << i);
}
private void GetUnmanagedBitMask()
{
fixed (uint* structPointer = InstanceBitMask)
{
for (int i = 0; i < uintNumberOfBits; i++)
for (int j = 0; j < uintNumberOfBits; j++)
((uint*)&structPointer[i])[j] = ((uint.MaxValue >> (uintNumberOfBits - j)) << i);
}
}
}
public class PointerTypeStaticFieldLab
{
static unsafe void Main()
{
UIntBitMask instance = new UIntBitMask(true);
Console.WriteLine("Pointers:");
Console.WriteLine("-----------------");
Console.WriteLine("Static bitmask pointer: 0x{0:X}", new IntPtr(UIntBitMask.StaticBitMask).ToInt64());
Console.WriteLine("Instance bitmask pointer: 0x{0:X}", new IntPtr(instance.InstanceBitMask).ToInt64());
Console.WriteLine();
Console.WriteLine("Values:");
Console.WriteLine("-----------------");
Console.WriteLine("Static bitmask pointer val: 0x{0:X}", UIntBitMask.StaticBitMask[0]);
Console.WriteLine("Instance bitmask pointer val: 0x{0:X}", instance.InstanceBitMask[0]);
}
}