Pointers in C#

Introduction:

C# provides very limited support for pointers. C# pointers are nothing but variables containing memory location of another type. C# pointers can only contain the memory location of value types and arrays. Pointers in C# are not tracked by the default garbage collection mechanism. For the same reason, pointers can not point to a reference type or structure type that contains a reference type.

C# Pointers can point to only basic data types like enum types, bool types, other pointers types, and structs that contain unmanaged data types, not reference types.

Declairation of C# Pointers:

The template of declaring a pointer in c#.

<type>* <name>;

The type is any unmanaged or value type and “*” is the de-reference operator. Let’s actually declare a pointer.

int x = 20;
int *ptr = & x;

In the above code “x” is an integer variable that contains a value and then we declared a pointer “ptr” that contains “x” memory address. “&x” is used for the memory address of “x”.

Example:

int x = 20;
int *ptr = & x;
Console.WriteLine((int)ptr) // // Displays the memory location 
Console.WriteLine(*ptr) // Displays the value at the memory location   

What is Unsafe code in C#?

Basically, C# has two types of code safe and unsafe code. By default, the code runs under common language run time (CLR) which is called safe code. In the safe code, the default Garbage Collector releases not-needed resources. To use unsafe code we have to use the “unsafe” keyword. While using an unsafe container the default garbage collector doesn’t release resources of the code that is declared in an unsafe block. In unsafe code, we need to call GC.Collect() or implement a mechanism to release the unused resource. Any C# code that has pointers requires an unsafe context.

We can use unsafe keywords in two different ways. In one way we can use the unsafe keywords as a modifier of the method, property, constructor, etc.

using System;  
class DemoClass  
{  
    public unsafe void Method()  
    {  
        int x = 5;  
        int y = 10;  
        int* ptr1 = &x;  
        int* ptr2 = &y;  
        Console.WriteLine((int)ptr1);  
        Console.WriteLine((int)ptr2);  
        Console.WriteLine(*ptr1);  
        Console.WriteLine(*ptr2);  
    }  
}  
class DemoClient  
{  
    public static void Main()  
    {  
        DemoClass  dc = new DemoClass();  
        dc.Method();  
    }  
}  

The unsafe keyword can also create a block of unsafe statements like below

using System;  
class DemoClass  
{  
    public void Method()  
    {  
        unsafe  
        {  
            int x = 5;  
            int y = 8;  
            int* ptr1 = &x;  
            int* ptr2 = &y;  
            Console.WriteLine((int)ptr1);  
            Console.WriteLine((int)ptr2);  
            Console.WriteLine(*ptr1);  
            Console.WriteLine(*ptr2);  
        }  
    }  
}  
class MyClient  
{  
    public static void Main()  
    {  
        DemoClass dc = new DemoClass();  
        dc.Method();  
    }  
}  

Pointers and Methods:

Pointers can be passed to methods as arguments and Methods can also return pointers. look below

using System;  
class DemoClass  
{  
    public unsafe void Method()  
    {  
        int x = 5;  
        int y = 10;  
        int* sum = letswap(&x, &y);  
        Console.WriteLine(*sum);  
    }  
    public unsafe int* letswap(int* x, int* y)  
    {  
        int sum;  
        sum = *x + *y;  
        return ∑  
    }  
}  
class DemoClient  
{  
    public static void Main()  
    {  
        DemoClass dc = new DemoClass();  
        dc.Method();  
    }  
}  

Pointers and Conversions:

Boxing and unboxing are not supported by pointers that means pointers are not inherited from objects. Any conversion between pointers & objects doesn’t exist in C#. But in C# conversion between different pointer types and pointer types and integral types is supported. In C# both implicit and explicit pointers conversions are supported.

The implicit conversions:

  • Any type pointer type to void * type.
  • Null type to any pointer type.

In explicit convert, the Cast() operator is needed. The explicit conversions:

  • Any pointer type to other pointer type.
  • int, uint, long, ulong sbyte, byte, short, ushort, to any pointer type.
  • Any pointer type to short, ushort, int, uint, long, ulong, sbyte, byte, types.

Example:

char b = 'R';  
char *pc = &b;  
void *pv = pc; // Implicit conversion  
int *pi = (int *) pv; // Explicit conversion using casting operator  

Pointers and Arrays:

In C# using pointers notation array elements can be accessed.

using System;  
class DemoClass  
{  
    public unsafe void Method()  
    {  
        int[] xArray = new int[10];  
        for (int count = 0; count < 10; count++)  
        {  
            xArray[count] = count * count;  
        }  
        fixed (int* ptr = xArray)  
            Display(ptr);
    }  
    public unsafe void Display(int* pt)  
    {  
        for (int i = 0; i < 14; i++)  
        {  
            Console.WriteLine(*(pt + i));  
        }  
    }  
}  
class DemoClient  
{  
    public static void Main()  
    {  
        DemoClass dc = new DemoClass();  
        dc.Method();  
    }  
}  

Pointers and Structures:

Structures are value types in C#. In C# pointers can be used with structures if it only contains value types.

Example:

using System;  
struct DemoStruct  
{  
    public int x;  
    public int y;  
    public void SetXY(int i, int j)  
    {  
        x = i;  
        y = j;  
    }  
    public void ShowXY()  
    {  
        Console.WriteLine(x);  
        Console.WriteLine(y);  
    }  
}  
class MyClient  
{  
    public unsafe static void Main()  
    {  
        DemoStruct ds = new DemoStruct();  
        MyStruct* ms1 = &ds;  
        ms1->SetXY(5, 10);  
        ms1->ShowXY();  
    }  
} 

Thank you for reading. Visit Mycodebit.com for .net core and .net tutorial

Leave a Reply

Your email address will not be published.