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

  • Organizations are increasingly gravitating toward mobile-first application development as they assess the need to revamp their application portfolios to support touch computing and mobility. Consumerization has brought higher expectations for application usability along with the mobile devices themselves. Enterprises are increasingly shifting their new application acquisitions and development efforts toward mobile platforms. With this backdrop, it is natural to expect application platform vendors to invest in …

  • By now you've likely heard of Agile development and building products in small incremental pieces, so you can get real feedback along the way. In fact, you may even be considering using Agile on your next project. But where do you start? Agile can take a lot of forms, such as Scrum or Kanban. Each form has advantages and disadvantages, but both will help your team get the right feedback they need to build great products. Read this white paper to find out which one is right for you.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date