C# Unsafe code

When a code block usesunsafeWhen marked with the modifier, C# allows the use of pointer variables in functions.Unsafe codeor unmanaged code refers to the use ofPointerVariable code block.

Pointer variables

PointerA pointer is a variable whose value is the address of another variable, that is, the direct address of a memory location. Like other variables or constants, you must declare a pointer before you can use it to store the address of another variable.

The general form of a pointer variable declaration is:

type* var-name;

Below is an example of pointer type declaration:

Example Description
int* p pis a pointer to an integer.
double* p pIt is a pointer to a double-precision number.
float* p pis a pointer to a floating-point number.
int** p pis a pointer to a pointer to an integer.
int*[] p pis a one-dimensional array of pointers to integers.
char* p pis a pointer to a character.
void* p pIt is a pointer to an unknown type.

When declaring multiple pointers in the same declaration, the asterisk*is written only with the base type; it is not used as a prefix for each pointer name. For example:

int* p1, p2, p3;     // 正确  
int *p1, *p2, *p3;   // 错误 

The following example illustrates the use ofunsafepointers in C# when the modifier is used:

Example

using System;
namespace UnsafeCodeApplication
{
    class Program
    {
        static unsafe void Main(string[] args)
        {
            int var = 20;
            int* p = &var;
            Console.WriteLine("Data is: {0} ",  var);
            Console.WriteLine("Address is: {0}",  (int)p);
            Console.ReadKey();
        }
    }
}

When the above code is compiled and executed, it produces the following results:

Data is: 20
Address is: 99215364

You can also avoid declaring the entire method as unsafe code, and only need to declare part of the method as unsafe code. The following example illustrates this.

Using Pointers to Retrieve Data Values

You can useToString()A method retrieves the data stored at the location referenced by the pointer variable. The following example demonstrates this:

Example

using System;
namespace UnsafeCodeApplication
{
   class Program
   {
      public static void Main()
      {
         unsafe
         {
            int var = 20;
            int* p = &var;
            Console.WriteLine("Data is: {0} " , var);
            Console.WriteLine("Data is: {0} " , p->ToString());
            Console.WriteLine("Address is: {0} " , (int)p);
         }
         Console.ReadKey();
      }
   }
}

When the above code is compiled and executed, it produces the following results:

Data is: 20
Data is: 20
Address is: 77128984

Passing Pointers as Method Parameters

You can pass pointer variables to a method as parameters. The following example illustrates this:

Example

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe void swap(int* p, int *q)
      {
         int temp = *p;
         *p = *q;
         *q = temp;
      }

      public unsafe static void Main()
      {
         TestPointer p = new TestPointer();
         int var1 = 10;
         int var2 = 20;
         int* x = &var1;
         int* y = &var2;
         
         Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
         p.swap(x, y);

         Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
         Console.ReadKey();
      }
   }
}

When the above code is compiled and executed, it produces the following results:

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

Using Pointers to Access Array Elements

In C#, an array name and a pointer to the same data type as the array data are different variable types. For example, int *p and int[] p are different types. You can increment the pointer variable p because it is not fixed in memory, but the array address is fixed in memory, so you cannot increment the array p.

Therefore, if you need to use a pointer variable to access array data, you can use, as we normally do in C or C++, thefixedkeyword to fix the pointer.

The following example demonstrates this:

Example

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe static void Main()
      {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)

         /* Display the array address in the pointer */
         for ( int i = 0; i < 3; i++)
         {
            Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
            Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
         }
         Console.ReadKey();
      }
   }
}

When the above code is compiled and executed, it produces the following results:

Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200

Compiling unsafe code

To compile unsafe code, you must switch to the command-line compiler and specify/unsafeCommand line.

For example, to compile a program named prog1.cs that contains unsafe code, you need to enter the command on the command line:

csc /unsafe prog1.cs

If you are using the Visual Studio IDE, you need to enable unsafe code in the project properties.

Steps:

  • Open by double-clicking the Properties node in Solution Explorer.Project properties (project properties)。
  • ClickBuildTab.
  • Select option"Allow unsafe code"。
other extensions