我在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管理指针(类型&)