Pointers and use of unsafe code in C#: should read

In this article I’ll explain pointers and use of unsafe code in C#. In the same example you will also understand the difference between value type and reference type (Stack / heap) so, let’s move ahead and do this.

In below section I’ll develop an example using unsafe code and will show how the addresses be allocated. In addition to this at the end of this article you will come to know how to build and work with unsafe code in C#.    

What this will cover:

  • Value type example given below.
  • Reference type example using int array.

Let’s check value type in below example:

We have taken int variable with value 100. We’ll try to change its value with in ‘UpdateNumber‘ function. Let’s see the code and its output below:

namespace Pointer_UnsafeCode
{
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                int num = 100;
                int* p = #
                Console.WriteLine("Data is: {0}  Address is: {1} ", num,  (int)p);
               
                Console.WriteLine("----Before calling 'UpdateNumber' method -----");
                UpdateNumber(num);
                Console.WriteLine("--- After calling 'UpdateNumber' method  --------");
                int* p2 = #
                Console.WriteLine("Data is: {0}  Address is: {1} ", num, (int)p2);
                Console.ReadLine();
            }
        }
        static void UpdateNumber(int num)
        {
            unsafe
            {
                num = 1111;
                int* p1 = #
                Console.WriteLine("Data is: {0}  Address is: {1} ", num, (int)p1);
             
            }
        }
    }
}

Let’s check out the addresses and the value before/ after calling ‘UpdateNumber’ method. Whole execution has been divided in three steps. Let’s discuss all these 3 steps below:

Pointers and use of unsafe code in C#

Step 1: Data value is 100 and its address is: 1961320 which is the actual address of our variable. Next, I’ll pass this value to UpdateNumber method and try to update it with in it. 

Step 2: With in UpdateNumber  method, see data value is 1111 and is address is: 1961212. Now notice we have new address 1961212, which means, within method value has been changed but new instance is created, and actual variable’s value of STEP 1 will remain the same (at its own address 1961320). Let’s re-confirm data value and address after executing the ‘UpdateNumber’ method.

Refer Step -3:  Data Value and address is exactly similar to STEP-1. Our UpdateNumber  methods has updated the value but for some separate instance not for the actual instance. Now data value which changed in Step-2, its scope is limited to UpdateNumber function only.

Conclusion

From above steps we can conclude that actual variable value did not change in ‘UpdateNumber’ method, and all this is happened because- int is of value type in nature.

In next example I’ll take Array of type int:

namespace Pointers_Array_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                int[] listData = { 10, 20, 30 };
                fixed (int* ptr = listData)
                    /* lets get array address using pointer */
                    for (int i = 0; i < 3; i++)
                    {
                        Console.WriteLine("Value at [{0}]={1}  Address is [{2}]={3}", i, *(ptr + i), i, (int)(ptr + i));
                       
                    }

                Console.WriteLine("--- Moving to 'UpdateValue' method ----");
                UpdateValue(listData);
                Console.WriteLine("----After executing 'UpdateValue' method ------");
                fixed (int* ptr2 = listData)
                    /* lets get array address in pointer */
                    for (int i = 0; i < 3; i++)
                    {
                        Console.WriteLine("Value at [{0}]={1}  Address is [{2}]={3}", i, *(ptr2 + i), i, (int)(ptr2 + i));
                    }

                Console.ReadKey();
            }
        }

        static void UpdateValue(int[] listData)
        {
            unsafe
            {

                listData[1] = 1111;
                fixed (int* ptr1 = listData)
                    for (int i = 0; i < 3; i++)
                    {
                        Console.WriteLine("Value at[{0}]={1}  Address is [{2}]={3}", i, *(ptr1 + i), i, (int)(ptr1 + i));
                    }
            }
        }
    }
}

In above sample we have taken int array like shown below

In above example we took int array and we’ll try to change its value within step-2 i.e., in ‘UpdateValue’ method. Whole execution of program is divided into 3 steps. Let’s discuss all three steps below.

     

int[] listData = { 10, 20, 30};

Step -1: Let’s check the data value and address before passing it to ‘UpdateValue‘ method.

Refer Step -2Now with in ‘UpdateValue‘ method we’ll try to update value at index [1] from 20 to 1111. Really strange, value got updated but addresses are similar as that in Step-1, whereas addresses were different in earlier example of value type int. Similar address indicates that it updates data in actual copy and does not create new copy.

Refer step -3: After executing the UpdateValue method let’s check the value and address again. Strange, it is with updated value. Why value updated this time?

Answer – It is because of “reference type” nature of int array.  

Please Note:

Without “Unsafe” keyword you’ll not be able to work with pointer in C#. Additionally, you need to do following settings only then your code will build else you will get error.

Please do the following setting to build the code.

  • Right click on project solution and select properties.
  • Select build option as shown below.
  • Last but not least check the checkbox “Allow unsafe code“.
  • Thats it, save and try to build, it will defiantly build successfully.

I hope in this article you have cleared your doubts regarding working with value types/reference type. If you have any question /suggestions, then feel free to post in comments. For more information on pointers in C# you can refer Microsoft learn.

For more information on value type and reference type please check out this article HERE

Leave a Reply

Your email address will not be published. Required fields are marked *