Easy Tutorial
❮ Csharp File Io Csharp Methods ❯

C# Unsafe Code

When a code block is marked with the unsafe modifier, C# allows the use of pointer variables within the function. Unsafe code or unmanaged code refers to code blocks that use pointers.

Pointer Variables

A pointer is a variable whose value is the address of another variable, i.e., the direct address of the memory location. Like any other variable or constant, you must declare a pointer before you can use it to store any variable address.

The general form of a pointer variable declaration is:

type* var-name;

Here are examples of pointer type declarations:

Example Description
int* p p is a pointer to an integer.
double* p p is a pointer to a double.
float* p p is a pointer to a float.
int** p p is a pointer to a pointer to an integer.
int*[] p p is a single-dimensional array of pointers to integers.
char* p p is a pointer to a char.
void* p p 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;     // Correct  
int *p1, *p2, *p3;   // Incorrect

The following example illustrates the use of pointers in C# when the unsafe 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 result:

Data is: 20
Address is: 99215364

You can also declare only a part of a method as unsafe code instead of declaring the entire method as unsafe. The following example illustrates this.

Retrieving Data Value Using Pointers

You can retrieve the data stored at the location referenced by the pointer variable using the ToString() method. 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 result:

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

Passing Pointers as Parameters to Methods

You can pass a pointer variable to a method as a parameter. 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 result:

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

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

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

Accessing Array Elements Using Pointers

In C#, the array name and a pointer to a data type identical to the array data type are not the same variable type. 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 an array address is fixed in memory, and hence, you cannot increment the array p.

Therefore, if you need to access the array data using a pointer variable, as we traditionally do in C or C++, you need to fix the pointer using the fixed keyword.

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 array addresses */
            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 result:

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 specify the /unsafe command-line switch with the command-line compiler.

For example, to compile a program named prog1.cs containing unsafe code, type the command:

csc /unsafe prog1.cs

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

Steps are as follows:

❮ Csharp File Io Csharp Methods ❯