Tags

,

Originally from here

Earlier I have already published a post on Pointers, which are very fascinating things in C and C++.

A pointer is a variable valued with the memory address another variable. Pointers maintain a common rule, like a variable or constant we need to define a pointer in order to store the variable or constant’s address. Pointers are very efficient, because we directly access to memory location with out code and much closer to the machine language. C# provides Pointer facility to us. But the limitation we have in C# pointers is we can hold only the memory address of value types and arrays. Sometimes this is an advantage because there is no real need of holding memory address of reference types as they might cause us deadlocks.

We define pointers in C# as they are defined in C / C++
[type] *[variable-name];
for example,
int *x;

Lets see an example, where we declare an instance data int a = 15; then declare a pointer which holds the memory location of the instance data a. So the code goes like

int a = 15;
int *pointer = &a;

remember, the followings are also valid, the place of * really doesn’t matter

int a = 15;
int* pointer = &a;

int a = 15;
int * pointer = &a;

but to maintain the code quality and naming conventions we use int *pointer. Now lets make this example real and try to make a console application with this.

using System;

namespace TestPointer
{
    class Program
    {
        static void Main(string[] args)
        {
             int a = 15;
             int* pointer = &a;
             Console.WriteLine(a);
             Console.WriteLine((int)pointer);
             Console.ReadLine();
        }
    }
}

This will return a compile time error, saying

first error

 

 

C# compiler never allow pointer operations by default, however using unsafe keyword we can define unsafe context where pointers can be used. So lets define it,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using System;

namespace TestPointer
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 15;
            Console.WriteLine(a);
            unsafe
            {
                int* pointer = &a;
                Console.WriteLine((int)pointer);
            }
            Console.ReadLine();
        }
    }
}

Now you can see, from line 13 to 14 we are using pointers and we should define unsafe context for those two lines, Its not a good practice to make unsafe context for all code. Now if we want to run this code, we again get another error

second error

As I mentioned above C# compiler does not allow unsafe codes, we have mentioned the compiler, that we have a unsafe part in our code by defining unsafe context now we have to instruct compiler to compile the code with unsafe. If you use csc.exe to compile the code with command prompt, you have to call csc.exe with /unsafe parameter. So if I want to compile my code with command prompt, I can say,
csc.exe /unsafe TestPointer.cs
Or I can use project properties, and under the “Build” tab of the project properties, I have “Allow Unsafe code”
allow unsafe code
If I run the above code after saving the project properties,
output

using fixed
Garbage collector automatically erase the instance variable a after it becomes unusable. Since objects in the memory are movable this makes garbage collection possible, but when we perform a pointer operation, the data should be in a fixed memory location, so we use fixed keyword. Remember you can’t use local variables, value parameters, and variables created by dereferencing pointers under fixed context, as the location of the variable is already fixed (you can refer more here)

Lets have a look at the example,

class Program
{
    unsafe static void Main(string[] args)
    {
        fixed (int * pointer = &Line.color)
        {
            Console.WriteLine((int)pointer);
        }

        Line line = new Line();
        fixed (int* pointer = &line.a)
        {
            Console.WriteLine((int)pointer);
        }

        Console.ReadLine();
    }
}

class Line
{
    public static int color;
    public int a;
}

But the below code will return a compile time error.

class Program
{
    unsafe static void Main(string[] args)
    {
        int a;
        fixed (int * pointer = &a)
        {
            Console.WriteLine((int)pointer);
        }

        Console.ReadLine();
    }
}

as we are using a already fixed variable.

Conclusion

Really there is no need for using pointers in C#, unless you are using an assembly from C++ that uses pointer. But as a programmer in C# you should know C# has the ability to perform pointer operation.

Happy coding.

Advertisements