Using Unsafe Code and Pointers in C#


One of the biggest features of the .NET platform is the support for type safety. This means that the Common Language Runtime – the engine of .NET - guarantees that there will not be any type errors  (issues which generally arise because of discrepancy between different data types for an application’s constants, variables and methods).

The benefits of type safety include:

  • Illegal operations are avoided.
  • No wild pointers – a pointer of one type is considered as pointer of other type
  • Avoiding buffer overflow

However, there are certain cases where you need access to code to unsafe code – code for which there is no guarantee of type security, e.g. pointers, or calling native APIs (DLLImport).

Any method, type or code block can be defined as unsafe using the unsafe C# keyword.

To compile the code, we need to use the “/unsafe” compiler flag.

Caveat: Tagging your code as unsafe can result in security risks in your code.

The Pointer Basics

In unsafe code, you can declare a type to be a pointer type.

The declaration is shown below:

type* typename;

For example, to declare a pointer to an int, we would declare it as:

int* ptr_MyVal;

If you want to declare multiple pointer types, we declare them as:

int* ptr_MyVal1, ptr_MyVal2;

Pointers can be declared for:

  • all scalar types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal and bool.
  • Enum types
  • Pointer types (pointers to pointers) (type**) - e.g. int**
  • User-defined structs

Let us take a look at a simple C# application to do some pointer arithmetic.

We will create a pointer and use the pointer to add a number to the pointee.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PointersDemo
    class Program
        static void Main(string[] args)
            int valueToBeOperated = 10;
                int* ptr_value = &valueToBeOperated;
                Console.WriteLine("valueToBeOperate = " + valueToBeOperated);
                Console.WriteLine("valueToBeOperate via pointer = " +  *ptr_value);
                *ptr_value += 10;
                Console.WriteLine("valueToBeOperate = " + valueToBeOperated);
                Console.WriteLine("valueToBeOperate via pointer = " + *ptr_value);

In the above listing, we are declaring a pointer to an int and then using the pointer reference to add 10 and then print the output.

To do this, you will have to do two things.

First, the code, which uses pointers will need to be declared in an unsafe context (see the highlighted section).

Next, we need to declare to the compiler  that we want to compile unsafe code. In Visual Studio, we can do it by changing the Project Properties.

Allow Unsafe Code
Allow Unsafe Code

This signals to the compiler to pass the “/unsafe”  flag to the csc.exe compiler.

The output of the above code is:

valueToBeOperate = 10
valueToBeOperate via pointer = 10
valueToBeOperate = 20
valueToBeOperate via pointer = 20

Next, we can take an advanced look to pointers.

In our second case, we will look at pointers to an array.

When we need pointers to objects in the heap, we need to use the fixed keyword to annotate the pointer, to indicate to the compiler that the objects must be fixed to avoid changing the location the pointer is referencing. This results in the object not moving when memory management operations are done.

// Listing 2- Array pointers

int[] myArray = new int[5] { 1, 2, 3, 4, 5 };

                fixed (int* ptr_array = &myArray[0])


                    int* ptr_ptr = ptr_array; // pointer to a pointer

                    Console.WriteLine("*ptr_array = " + *ptr_array);

                    Console.WriteLine("**ptr_ptr = " + *ptr_ptr);

                    *ptr_array += 10;

                    Console.WriteLine("*ptr_array = " + *ptr_array);

                    Console.WriteLine("**ptr_ptr = " + *ptr_ptr);


                    Console.WriteLine("*ptr_array (does not change) = " + *ptr_array);

                    Console.WriteLine("**ptr_ptr (changes to the next array element) = " + *ptr_ptr);


In the above snippet, we declare a pointer to an array, ptr_array. Notice that we need to decorate it with the fixed keyword (highlighted).

When we add 10 to *ptr_array, we are actually dereferencing to the first element and adding 10.

When we increment ptr_ptr (pointer to the pointer to the array), we are telling the pointer to move to the next array element.

The output of the above snippet is:

*ptr_array = 1
**ptr_ptr = 1
*ptr_array = 11
**ptr_ptr = 11
*ptr_array (does not change) = 11
**ptr_ptr (changes to the next array element) = 2

The complete listing of the above code including a working Visual Studio 2013 project is available at PointersDemo



In this article, we learned about using unsafe code and pointers in C#. I hope you have found this information useful.

About the Author

Vipul Patel is a Program Manager currently working at Amazon Corporation. He has formerly worked at Microsoft in the Lync team and in the .NET team (in the Base Class libraries and the Debugging and Profiling team). He can be reached at

Related Articles



  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Hybrid cloud platforms need to think in terms of sweet spots when it comes to application platform interface (API) integration. Cloud Velocity has taken a unique approach to tight integration with the API sweet spot; enough to support the agility of physical and virtual apps, including multi-tier environments and databases, while reducing capital and operating costs. Read this case study to learn how a global-level Fortune 1000 company was able to deploy an entire 6+ TB Oracle eCommerce stack in Amazon Web …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds