Pointers and Unsafe Coding in C#

Discussion in 'C#' started by shabbir, Feb 17, 2014.

  1. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    C# is a language that integrates useful concepts from several programming languages. C# contains advanced features of Java and provided C++’s robustness. The concept of pointer is integral in C and other low level languages. However, C# also allows you to utilize the power of pointers in your code via unsafe code and pointer options.
    Pointers are basically a way to access memory address of a value type or a pointer.
    When you write the following line of code
    Code:
    int a, b;
    b= 10;
    a = b;
    b = 20;
    a = 15;
    
    What happens is that the compiler creates two variables of type integer; assigns 10 to ‘b’ and then assigns ‘b’ to ‘a’. Now, variable ‘a’ contains the value of ‘b’ i.e 10. Now if the value of ‘b’ is changed in the next line it will have no impact on the value of ‘a’, although we assigned ‘a’, the value of ‘b’. This is due to the reason that ‘a’ has stored the value of ‘b’, not its memory address. Similarly if we change the value of ‘a’ in the next line it will have no impact on the value of ‘b’ because both ‘a’ and ‘b’ has different memory address in the memory.
    Pointer is a different concept and is often times considered complicated. However, with careful attention to this article and with little bit of practice you can easily grasp the concept and implement it in your code.

    In order to use pointers in your C# code, you need remember the following three operators. They are vital to using pointers in C#.

    Address-Of Operator

    This is denoted by ampersand ‘&’. This operator returns the pointer to the memory address of the variable.

    Dereference Operator

    This is denoted by a steric ‘*’. This operator has the functionality opposite to that of address-of operator. It returns the variable located at the address of the pointer.

    Pointer-to-member Operator

    This denoted by ->. Actually pointer-to-member function is a shorthand notation in which x->y is actually equal to (*x).y, which means that return the variable located at pointer x and multiply it with y.

    Now you would have understood the basics of pointer. Another very important point to be noted here is that whenever you use pointers in your code you will have to enclose them in unsafe block and you will have to compile that code with unsafe compiler option. When you mark a block of code unsafe, you are actually telling the compiler that allow the pointer variables to manipulate the memory address of the program, which are within the unsafe code block. Since you are directly manipulating the memory addresses when you use pointers, you will have to declare that block of code unsafe. However, an unsafe code is faster in terms of performance as compared to ordinary safe code. Now we will move towards our first example which elaborates the use of pointers in C#. Have a look at the first Example.

    Example1

    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Dynamic;
    
    namespace CSharpTutorial
    {
        class Program
        {
            static unsafe void Main(string[] args)
            {
                int b = 20;
                int* a = &b;
                Console.WriteLine("Value of b is: " + b);
                Console.WriteLine("Value of a is: " + *a);
                Console.WriteLine("Memory Address of a is: " + (int)a);
              
                *a = 10;      
                Console.WriteLine("\nValue of b is: "+ b);
                Console.WriteLine("Value of a is: " + *a);
                Console.WriteLine("Memory Address of a is: " + (int)a);
      
                b = 25;
                Console.WriteLine("\nValue of b is: " + b);
                Console.WriteLine("Value of a is: " + *a);
                Console.WriteLine("Memory Address of a is: " + (int)a);          
                Console.ReadLine();
            }
        }
    }
    
    Carefully look at the code in Example1. First of all, we have appended the keyword unsafe after the keyword static in the main function declaration. This will tell the compiler that inside the main function, allow the code logic to access the memory address of the program within the main function. We have declared a variable of type int and we have named it ‘b’. Next we declared a pointer that can hold an integer. Declaring a pointer in C# is similar to C and C++. You just have to insert a steric between the type and the pointer name. For example, in Example1, we have declared a pointer of type integer named ‘a’ as

    int * a ;

    This means that ‘a’ can hold the memory address of any variable or literal of type integer. In the next line we assigned the memory address of integer ‘b’ to pointer a using the address-of operator &. Now the pointer ‘a’ contains the memory address of variable ‘b’ which means that basically memory address of variable ‘b’ can now be accessed via ‘b’ as well as the pointer ‘a’.
    Now, in order to access the memory address stored in the pointer a you will simply have to access pointer ‘a’. However, if you want to get the value that is stored in the memory address to which our pointer ‘a’ is referring, you will have to use dereference operator steric ‘*’ which will fetch the value that is stored in memory address.

    Again coming back to our code in Example1, we have initialized the integer type variable ‘b’ with value 20. As pointer ‘a’ points to the memory address of ‘b’ therefore the value stored in the memory address of pointer ‘a’ should also be 20. In the next lines we have displayed the value of ‘b’, the value stored in the memory address of pointer ‘a’ and the memory address of pointer ‘a’ which will be any number. The output shows that both the value of ‘b’ and pointer ‘a’ would be the same.

    In the next line we have changes the value stored in the memory address contained by pointer ‘a’. We have changed it to 10. Since the memory address stored in pointer is the memory address of the integer variable ‘b’, now the value of ‘b’ will also be 10. We have again printed the value of ‘b’, the value stored in the memory address contained by pointer ‘a’ and the memory address of ‘a’. You will see that new values of ‘b’ and ‘a’ would be 10. That shows that changing the value of ‘a’ also changes the value of ‘b’.

    Next we have proved that changing the value of ‘b’ would change the value of ‘a’. We have now assigned ‘b’ the value 25. And now if we print the value of ‘b’ and the value stored in the memory address contained by pointer it would be same i.e 25.

    We mentioned earlier in the article that in order to use pointers in the code, we will have to allow the compiler to compile the unsafe code. We wrote our code in VS 2010. In order to compile unsafe code in visual studio, do the following steps:
    1. Right click on the project name and click the properties.
    2. Click the build on the options in the left side.
    3. Check the ‘Allow unsafe code’ option.
    Now when you compile the code, it will compile without any error in VS 2010, otherwise it would not compile. The output of the code in Example1 would be as follows.

    [​IMG]

    Passing Parameters by reference using pointers



    Pointers are also used to pass parameters by reference to the methods. Before explaining how pointers do this, let us first discuss difference between passing parameters by value and passing by reference.

    When you pass the argument to a normal method, a copy of the arguments is locally generated whose scope is within the method to which variables are being passed. If method modifies these copies of the arguments, the actual arguments don’t get modified. This is called passing by reference.

    Passing by reference is a different in a sense that instead of passing the values of the parameters, the reference to the parameters is passed to the method. The method actually operates on the reference of the parameters being passed. Therefore, if the function modifies these values, they are also modified in the calling function.

    We will take help of an example to further elaborate this concept that how pointers are used in passing parameters by reference to a function. Have a look at Example2.

    Example2
    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Dynamic;
    namespace CSharpTutorial {
        class Program {
            public static unsafe void swapvalues(int* a, int *b) {
                int temp = *a;
                *a = *b;
                *b = temp;
            }
            public unsafe static void Main() {
                int num1 = 25;
                int num2 = 50;
                int* a = &num1;
                int* b = &num2;
                Console.WriteLine("Before swapping num1 = "+num1 +". num2 = " +num2);
                swapvalues(a, b);
                Console.WriteLine("After swapping num1 = " + num1 + ". num2 = " + num2);
                Console.ReadLine();
            }
        }
    }
    
    Now closely look at the code in Example2, we have a method named swapvalues which takes two reference type parameters. Inside the method it stores the value contained by one reference variable ‘a’ in a temporary variable ‘temp’. Then it stores the value contained by the memory address of second reference ‘b’ in the memory address contained by pointer ‘a’. In the last line of the swapvalues method, we have stored the memory address of temp variable in pointer ‘b’. In this way we have swap the values.

    But how values have been swapped? We haven’t returned anything. This is the beauty of using pointers, you didn’t returned anything yet you are able to manipulate the variables in the calling function because you do not create a copy of the passed parameters, rather you use a reference of those variable and hence the original values of those variables is also modified.
    Another huge advantage of using pointers is that it allows you to have a workaround for returning multiple variables from a function. Normally, a function can only return single value when you pass parameters by value. However, when you pass parameters by reference you can manipulate multiple numbers of variables in the calling function or in other words, you are returning multiple values from a function.

    Inside the main method we have declared two variables, namely num1 and num2. We have stored 25 and 50 in both of these integer type variables respectively. We then declared two pointers ‘a’ and ‘b’ and stored the memory address of integer variables num1 and num2 in these pointers, respectively. We then displayed the values of both num1 and num2. At that time num1 would contain 25 and num2 would contain 50. We then called the swapvalues method and passed the pointers ‘a’ and ‘b’ to the method as reference parameters. The swapvalues method would swap the values as discussed earlier. Then we have again displayed the values of integer variables num1 and num2 which would now contain swapped values 50 and 25. The output of Example2 is as follows.

    Output2

    [​IMG]

    Pointer to Member Operator



    We have explained all the basic pointer concepts except the usage of pointer to member operator ->. This is mostly used with structs and classes. We will explain this with the help of an example, how this can be used in your code.

    Example3

    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Dynamic;
    
    namespace CSharpTutorial
    {
        struct PTM
        {
            int a;
            unsafe static void Main()
            {
                PTM ptm = new PTM();
                PTM* p = &ptm;
                p->a = 25;
    
                Console.WriteLine(ptm.a);
                Console.ReadLine();
            }
        }
    }
    
    The code in Example3 is self-explanatory; We have declared a struct named PTM which has one member, an integer named ‘a’. Inside the main method we have created an instance ptm of struct PTM. Then we have declared a pointer ‘p’ that can refer to memory address of any struct PTM. Now in order to access member ‘a’ of struct PTM from this pointer ‘p’ we can use pointer to member operator ‘->’ which we have done in this line p->a = 25. Here we are telling the pointer to access the member of sruct object ptm and store value 25 in it. Now if we display the value of a using simple ptm object, it will contain the value 25 as shown in the output.

    Output3

    [​IMG]
     
    Last edited: Jan 21, 2017

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice