Updated March 17, 2023
Introduction to Pointers in C#
Pointers are defined as a variable that contains the memory address of another variable. Pointers in C# are used whenever there is a statement that is unsafe and is marked by unsafe keyword. Those types of statements are not in control of garbage collectors and use pointer variables.
Syntax: Pointers can be declared as
type *var name;
int* a;
Here * is called a de-reference operator and a is the variable that contains the address of type int.
Example
int *p = & x; // where &x is the memory address of x
Console.WriteLine((int)p) // displaying memory address
Console.WriteLine(*p) // displaying value at memory address
How does Pointers work in C#?
Below are the examples that show how it works in C#.
Pointers in C# – Example #1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public void Method()
{
unsafe
{
int a = 40;
int b = 20;
int* ptr1 = &a;
int* ptr2 = &b;
Console.WriteLine(*ptr1); // displaying the value
Console.WriteLine(*ptr2); // displaying the value
Console.WriteLine((int)ptr1); // displaying the address
Console.WriteLine((int)ptr2); // displaying the address
}
}
}
class Example
{
// main method
public static void Main()
{
Demo d = new Demo();
d.Method();
}
}
}
There are different ways to execute statements as unsafe like a Modifier, constructor, etc. In the above example, a group of statements are marked as unsafe. In the above code, there are two variables a and b with values 40 and 20 respectively and pointers contain their addresses. Console.WriteLine() is used to display the values and addresses of the variables.
Output:
Pointers in C# – Example #2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public unsafe void Method()
{
int a = 50;
int b = 20;
int* ptr1 = &a;
int* ptr2 = &b;
Console.WriteLine(*ptr1); // displaying the value
Console.WriteLine(*ptr2); // displaying the value
Console.WriteLine((int)ptr1); // displaying the address
Console.WriteLine((int)ptr2); // displaying the address
}
}
class Example
{
// main method
public static void Main()
{
Demo d = new Demo();
d.Method();
}
}
}
In the above example, unsafe is used with the method which has two variables a and b with values 50 and 20 respectively. Pointers *ptr1 and *ptr2 points to their memory addresses.
Output:
Pointers in C# – Example #3
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public unsafe static void Main()
{
int[] array = { 10, 20, 30, 40, 50 }; // declaring array
fixed (int* ptr = array) // fixed for pinning the object
/* let us have array address in pointer */
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Value of array[{0}]={1}", i, *(ptr + i));
Console.WriteLine("Address of array[{0}]={1}", i, (int)(ptr + i));
Console.ReadKey();
}
}
}
}
In the above code, an array is defined which consists of five elements and Console.WriteLine () is used to display the value of array elements and the address of the array elements. There is a concept in C# which is known as the Pinning of an object. In the above code, a fixed statement is used for object pinning so that the garbage collector will not let the object to move and “pin” it. It may affect the runtime efficiency.
Output:
Pointers in C# – Example #4
using System;
namespace Pointers
{
// Struct employee
struct Employee
{
// members
// employee id and salary
public int empid;
public double salary;
// Constructor to initialize values
public Employee(int e, double s)
{
empid = e;
salary = s;
}
}; // end of struct
class Program
{
// Main Method
static void Main(string[] args)
{
// unsafe so as to use pointers
unsafe
{
// Declaring two employee Variables
Employee E1 = new Employee(798, 30000);
Employee E2 = new Employee(799, 31000);
// Declaring two employee pointers
// and initializing them with addresses
// of E1 and E2
Employee* E1_ptr = &E1;
Employee* E2_ptr = &E2;
// Displaying details of employees using pointers
// Using the arrow ( -> ) operator
Console.WriteLine("Details of Employee 1");
Console.WriteLine("Employee Id: {0} Salary: {1}",
E1_ptr->empid, E1_ptr->salary);
Console.WriteLine("Details of Employee 2");
Console.WriteLine("Employee Id: {0} Salary: {1}",
E2_ptr->empid, E2_ptr->salary);
} // end unsafe
} // end main
} // end class
}
In the above example, employee struct with members employee id and salary and parameterize constructor to initialize the values. Pointers point to structs which contain primitive value type instead of structs containing reference type. In main method, there are two employee variables and employee pointers which are initialized with addresses E1 and E2. Console.WriteLine() is used to display the details of the employee using pointers.
Output:
Pointers in C# – Example #5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointers
{
class Demo
{
public static void Main()
{
unsafe
{
int* arr = stackalloc int[6]; // declaring array
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
arr[5] = 60;
for (int i = 0; i < 6; i++)
{
Console.WriteLine($"Value at {i}: {arr[i]}");
Console.ReadKey();
}
}
}
}
}
In the above code, the stackalloc keyword is used, in which memory is allocated on the stack. The memory executed on the block of stack is created during the method execution. stackalloc is better in performance and there is no need to pin the array. It is better than the heap-allocated array as there is no need to free it because it automatically freed when the method returns.
Output:
In pointers, conversions are of an implicit and explicit type. An implicit type of conversion is like any pointer type to void* type and null to any pointer type. In explicit type, conversions are from byte, sbyte, ushort, short, uint, int, ulong, long to any pointer type or vice versa and one pointer to another pointer.
Conclusion – Pointers in C#
So pointers are used to point the memory addresses and execute them with an unsafe code of statements. It only used in an unmanaged environment and is not tracked by the garbage collector. Pointers are used in a stack, queue, etc.
Recommended Articles
This is a guide to Pointers in C#. Here we discuss Introduction and how does pointer work in C# along with various Examples. You may also look at the following articles to learn more-