Skip to main content

UNIT – 6 : POINTERS IN C#


1. Introduction to Pointers in C#

A pointer is a variable that stores the memory address of another variable.
In C#, pointers are allowed only inside unsafe code, and they work only with value types and arrays.

Pointer Declaration Syntax

datatype* pointerName;

Example:

int* ptr;

·         Pointers are allowed only in unsafe context.

·         C# pointers are similar to C/C++ pointers but with more restrictions for safety.

2. Features of Pointers in C#

·          Pointers save memory space.

·          Execution is faster due to direct memory access.

·          Memory access becomes more efficient.

·          A pointer cannot point to:

o    A reference type

o    A struct containing reference fields

·          The type before * is called the referent type.

·          Pointers can be used only inside unsafe blocks.

Example:

unsafe
{
    int x = 5;
    int* p = &x;
}

3. Unsafe Code

In C#, unsafe code allows pointer operations.

Properties of Unsafe Code

·         Methods, types, and blocks can be marked with unsafe.

·         Pointer operations allow:

o    Direct memory access

o    Faster execution

o    Removing array bounds checks

·         Necessary for calling native/OS-level functions.

·         Risky because:

o    CLR cannot fully check safety

o    Memory corruption may occur

·         The project must enable: AllowUnsafeBlocks

4. Enabling Unsafe Code

In Visual Studio Code (.csproj file):

Open .csproj and add:

<PropertyGroup>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

In Visual Studio IDE:

Project → Properties → Build → Check "Allow unsafe code".

 ADVANTAGES OF UNSAFE CODE

·         Better performance because there are no runtime safety checks.

·         Direct memory access using pointers and fixed buffers, allowing faster raw memory operations.

·         Useful for system-level tasks where low-level control of memory is required.

 DISADVANTAGES OF UNSAFE CODE

·         Higher security risk because the CLR cannot fully protect or check the code.

·         More chances of errors since type safety and bounds checking are bypassed.

·         Unsafe pointer access can break object access rules, leading to memory corruption or crashes.

 
Example
using System;
 
class MyClass
{
    public unsafe void Method()
    {
        int x = 10;
        int y = 20;
 
        int* ptr1 = &x;
        int* ptr2 = &y;
 
        Console.WriteLine((int)ptr1); // Memory address
        Console.WriteLine((int)ptr2); // Memory address
        Console.WriteLine(*ptr1);     // Value at address
        Console.WriteLine(*ptr2);     // Value at address
    }
}
 
class MyClient
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        mc.Method();
    }
}

CALL BY VALUE

•	When you pass a variable to a method by value, C# sends only a copy of the data.
•	Inside the method, any changes are applied to the copy, not the original variable.
•	Therefore, the original variable remains unchanged.
How It Works Internally
Original Variable → Copy Created → Method Uses Copy → Changes Stay Inside
Example Program 
using System;

class Program
{
    static void ModifyValue(int x)
    {
        x = 20; // This only changes the COPY
    }

    static void Main()
    {
        int num = 10;
        
        Console.WriteLine("Before ModifyValue: " + num);  

        ModifyValue(num);  // Passing by VALUE (copy)
        
        Console.WriteLine("After ModifyValue: " + num);   
    }
}
Output
Before ModifyValue: 10
After ModifyValue: 10

2. CALL BY REFERENCE USING ref


•	ref sends the actual memory address of the variable.
•	So the method can directly modify the original variable.
•	Variable must be initialized before passing.
How It Works Internally
Original Variable → Address Sent → Method Changes Actual Value
Example Program 
using System;

class Program
{
    static void ModifyValue(ref int num)
    {
        num = num * 2;  // This modifies the original variable
    }

    static void Main()
    {
        int number = 5; // Must be initialized
        
        Console.WriteLine("Before: " + number);  
        
        ModifyValue(ref number);  // Passing by reference
        
        Console.WriteLine("After: " + number);  
    }
}
Output
Before: 5
After: 10
Explanation
•	ref sends the actual memory location
•	Method modifies the real value, not a copy
•	So change is permanent

3. CALL BY REFERENCE USING out


•	out is also used to pass by reference.
•	But the variable does NOT need to be initialized before passing.
•	The method must assign a value before it returns.
How It Works Internally
Uninitialized Variable → Address Sent → Method Must Assign Value
Example Program 
using System;

class Program
{
    static void SetValue(out int num)
    {
        num = 10;  // Must assign value
    }

    static void Main()
    {
        int number; // Uninitialized variable
        
        SetValue(out number);  // Passed by reference
        
        Console.WriteLine("Value: " + number);
    }
}
Output
Value: 10
Explanation
•	Variable number was not initialized.
•	out allows uninitialized variables.
•	Method must set the value → num = 10.

RETRIEVING THE DATA VALUE USING A POINTER

A pointer is a variable that stores the memory address of another variable.

Example:

int a = 10;
int* p = &a;

·         a stores value 10

·         &a returns the memory address of a

·         p stores that address

Dereferencing a Pointer

The * operator is used to read the value from the memory address.

Example Code:

using System;
 
class Program
{
    unsafe static void Main()
    {
        int a = 100;
        int* p = &a;
 
        Console.WriteLine("Value of a: " + a);
        Console.WriteLine("Address of a: " + (int)p);
        Console.WriteLine("Value using pointer: " + *p);
    }
}

How it works:

&a

Address of variable a

P

Holds address

*p

Reads value from that address

Memory Model:

If:

a = 100
address = 2001

Then:

p = 2001
*p = 100

PASSING POINTER AS PARAMETER TO METHODS

Passing a pointer as a parameter means sending the memory address of a variable instead of its value, so the method can modify the original variable directly.
Normal parameters pass a copy, but pointer parameters pass the address.
Syntax:
unsafe void Method(int* p) and call using Method(&variable);

Example: Swap Two Numbers Using Pointers

using System;
 
class Program
{
    unsafe static void Swap(int* x, int* y)
    {
        int temp;
 
        temp = *x;
        *x = *y;
        *y = temp;
    }
 
    unsafe static void Main()
    {
        int a = 10;
        int b = 20;
 
        Console.WriteLine("Before Swap:");
        Console.WriteLine("a = " + a);
        Console.WriteLine("b = " + b);
 
        Swap(&a, &b);
 
        Console.WriteLine("\nAfter Swap:");
        Console.WriteLine("a = " + a);
        Console.WriteLine("b = " + b);
    }
}

&a passes the address, int* x receives and stores it, and *x = value changes the original variable.
Final result: the actual values in memory are modified (e.g., swapping is done).

Output

Memory Before:

a = 10    b = 20

Memory After:

a = 20    b = 10

 

ACCESSING ARRAY ELEMENTS USING A POINTER

In c# int *p and int[] p, are not the same type. You can increment the pointer variable p because it is not fixed in memory but an array address is fixed in memory, and you can't increment that.  We need to fix the pointer using the fixed keyword to access the array elements using pointer.

Read Array Using Pointer

using System;
 
class Program
{
    unsafe static void Main()
    {
        int[] arr = { 10, 20, 30, 40, 50 };
 
        fixed (int* ptr = arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                Console.WriteLine(*(ptr + i));
            }
        }
    }
}

 

fixed locks the array in memory, ptr holds the first element’s address, ptr + i moves to the next element, and *(ptr + i) reads its value.

Example 2: User Input + Pointer

using System;
 
class Program
{
    unsafe static void Main()
    {
        Console.Write("Enter size: ");
        int n = int.Parse(Console.ReadLine());
 
        int[] arr = new int[n];
 
        for (int i = 0; i < n; i++)
        {
            Console.Write("Enter element " + (i + 1) + ": ");
            arr[i] = int.Parse(Console.ReadLine());
        }
 
        fixed (int* ptr = arr)
        {
            Console.WriteLine("\nAccessing using pointer:");
            for (int i = 0; i < arr.Length; i++)
            {
                Console.WriteLine(*(ptr + i));
            }
        }
    }
}

How it Works:

1.      Takes array size

2.      Accepts elements

3.      Fixes memory

4.      Uses pointer arithmetic

5.      Dereference

6.      Prints values


Comments

Popular posts from this blog

Function of OS 1. Process Management The operating system helps in running many programs at the same time. It keeps track of each running program (called a process), decides which one should run next, and stops or starts them as needed. It makes sure that all the programs get a fair chance to use the CPU.   2. Memory Management The OS manages the computer's memory (RAM). It decides which program will use how much memory and keeps track of it. When a program is closed, it frees up the memory so that other programs can use it. This helps the computer run smoothly without crashing.   3. File System Management The operating system helps us to create, save, open, and delete files. It organizes files in folders and keeps them safe. It also controls who can open or edit a file to protect our data.   4. Device Management The OS controls all the input and output devices like the keyboard, mouse, printer, and monitor. It tells the devices what to do and makes su...

UNIT 3 Array in C#

  Array in C# An array is a collection of variables of the same data type , stored in contiguous memory locations , and accessed using a common name and index . Each item in an array is called an element , and the index of arrays in C# starts from 0 .     Key Points About Arrays in C#: 1.       Elements are stored in contiguous memory locations. 2.       Index starts from 0. So, for an array of size 5, valid indexes are 0 to 4. 3.       Arrays are reference types and are allocated on the heap. 4.       C# array is an object of base type System.Array . 5.       Array elements can be of any type , including another array (array of arrays). 6.       Jagged array (array of arrays) elements are reference types and are initialized to null . 7.       Arrays can be single-dimensi...

Unit 2 Java

Data Types A data type defines the kind of data a variable can store, the operations that can be performed on it, and the amount of memory allocated. Java Primitive Data Types Data Type Size Range (Approx.) Example Byte 1 byte -128 to 127 byte a = 100; short 2 bytes -32,768 to 32,767 short s = 1000; Int 4 bytes -2,147,483,648 to 2,147,483,647 int num = 50000; Long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 long l = 100000L; float 4 bytes ~6–7 decimal digits float f = 5.75f; double 8 bytes ~15 decimal digits double d = 19.99; Char 2 bytes Single Unicode character char c = 'A'; boolean 1 bit* tru...