我在msdn上遇到了以下代码:
unsafe static void SquarePtrParam (int* p) { *p *= *p; } unsafe static void Main() { Point pt = new Point(); pt.x = 5; pt.y = 6; // Pin pt in place: fixed (int* p = &pt.x) { SquarePtrParam (p); } // pt now unpinned. Console.WriteLine ("{0} {1}",pt.x,pt.y); }
我只是想知道,我们是直接访问SquarePtrParam函数中的指针,它是否继承了从调用方法修复数组的信息?
为什么我们不需要在SquarePtrParam中将其明确设置为本地修复.
我想我可以使用一些关于这个固定语句的详细说明.
解决方法
固定语句实现unpin内存区域的方式与“using”语句关闭打开的文件一样使用(FileStream stream = new FileStream(..))构造.在您离开固定代码块之前,内存将被固定.
在IL代码中,它将创建虚拟PINNED局部变量并将指针存储到其中.这将不允许GC移动内存区域包含此指针.在您离开固定块后,它将零存储到此PINNED变量中.像这样:
public static unsafe void TestInternal(byte* pointer) { Console.WriteLine((IntPtr)pointer); } public static void FixedDemo() { Byte[] newArray = new Byte[1024]; unsafe { fixed (Byte* pointer = &newArray[0]) { TestInternal(pointer); } } Console.WriteLine("Test Complete"); }
所以IL Code中的FixedDemo:
.method public hidebysig static void FixedDemo() cil managed { // Code size 47 (0x2f) .maxstack 2 .locals init ([0] uint8[] newArray,[1] uint8& pinned pointer) IL_0000: nop IL_0001: ldc.i4 0x400 // Put 1024 on the stack IL_0006: newarr [mscorlib]System.Byte // allocate new array of 1024 length IL_000b: stloc.0 // Store it in local variable 0 IL_000c: nop IL_000d: ldloc.0 // Put local variable 0 on the stack IL_000e: ldc.i4.0 // Put zero on the stack IL_000f: ldelema [mscorlib]System.Byte // Load address of zero index from array IL_0014: stloc.1 // !!! Here we pin memory by storing it in pinned variable IL_0015: nop IL_0016: ldloc.1 // Load function argument IL_0017: conv.i // Perform conversion IL_0018: call void FinMath.Tests.Program::TestInternal(uint8*) IL_001d: nop IL_001e: nop IL_001f: ldc.i4.0 // Load zero on the stack IL_0020: conv.u // Perform conversion IL_0021: stloc.1 // !!!! Here we unpin memory IL_0022: nop IL_0023: ldstr "Test Complete" // Load string IL_0028: call void [mscorlib]System.Console::WriteLine(string) // Out message IL_002d: nop IL_002e: ret } // end of method Program::FixedDemo
欲了解更多信息,请访
> MSDN
> MSDN Magazine: Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
> Common language Runtime standard ECMA 335分区III,1.1.4.2管理指针(类型&)