Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# unsafe code fixed pointer passed as parameter

Tags:

c#

fixed

unsafe

I came across the following code on 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);
        }

I am just wondering, we are directly accessing pointer in SquarePtrParam function, does it inherit information that array is fixed from calling method?

Why don't we need to explicitly set it to fixed locally in SquarePtrParam.

I guess I could use some elaborations about this fixed statement.

like image 353
Valentin Kuzub Avatar asked Nov 11 '11 14:11

Valentin Kuzub


People also ask

What C is used for?

C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Why is C named so?

Quote from wikipedia: "A successor to the programming language B, C was originally developed at Bell Labs by Dennis Ritchie between 1972 and 1973 to construct utilities running on Unix." The creators want that everyone "see" his language. So he named it "C".


1 Answers

Fixed statement implement unpin memory area in the same manner as "using" statement close opened files in using(FileStream stream = new FileStream(..)) construction. Memory will be pinned until you left the fixed code block.

In the IL code it will create dummy PINNED local variable and store a pointer into it. This will not allow GC move memory area contains this pointer. After you will left fixed block it will store zero into this PINNED variable. Just like this:

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");
}

So FixedDemo in IL Code:

.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

For more information visit:

  1. MSDN

  2. MSDN Magazine: Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework

  3. Common language Runtime standard ECMA 335 Partition III, 1.1.4.2 Managed Pointer (type &)

like image 98
Wisdom's Wind Avatar answered Nov 03 '22 23:11

Wisdom's Wind