Home | Created on - November 2005
A lot of C programmers could not digest Java was because Java didn't let them manipulate pointers. Anyway C# supports pointers. You can use the unsafe keyword to inform the compiler that the following function or block is unsafe. And once you do that you can use pointers in that unsafe area.
using System;
class infosrama
{
unsafe static void Increment(int* p)
{
//increment the int pointed to by p
*p=*p+1;
}
public static void Main()
{
int i = 1;
//we pass the address of the int to the function as it expects a pointer
unsafe
{
Increment(&i);
}
//now we print out the value of i
Console.WriteLine (i);
}
}
When you run the program, you'll see 2 printed on screen. This is because you
have passed the address of the variable i to the function Increment. Variable i
is created on the stack. &i gives its address on the stack. Thus when within
the function Increment, p is pointing to i's address. Thus when we add 1 to *p
we are actually incrementing i
Program 2
using System;
class infosrama
{
unsafe public static int Main()
{
int j=100;
int k=100;
Console.WriteLine("address of j={0} and address of k={1}",
(int)&j,(int)&k);
Console.WriteLine("j={0} k={1}",j,k);
int *p;
p=&j;
Console.WriteLine("p now points to {0}",(int)p);
*p=200;
Console.WriteLine("j={0} k={1}",j,k);
p=&k;
Console.WriteLine("p now points to {0}",(int)p);
*p=300;
Console.WriteLine("j={0} k={1}",j,k);
return 0;
}
}
When I ran it I got the below output. You would get something similar. The output will clearly give an idea of what's going on.
address of j=1244312 and address of k=1244308 j=100 k=100 p now points to 1244312 j=200 k=100 p now points to 1244308 j=200 k=300
Program 3
Okay. In this final program I'll show you how to use pointers to manipulate a
character string. In this program there is a function that takes a string and
encodes or decodes it using XOR. If you pass a string to it it will encode it
and if you pass the encoded string to it, it will decode it. Of course this is
by no way a safe or practical encryption method. I am using it merely to
demonstrate the use of pointers.
using System;
class infosrama
{
public static void Main()
{
string s="Code Project is cool";
Console.Write("the original string : ");
Console.WriteLine("{0}\r\n",s);
char[] b = new char[100];
s.CopyTo(0,b,0,20);
Console.Write("the encoded string : ");
unsafe
{
fixed(char *p=b)NEncodeDecode(p);
}
for(int t=0;t<20;t++)
Console.Write(b[t]);
Console.WriteLine("\r\n");
Console.Write("the decoded string : ");
unsafe
{
fixed(char *p=b)NEncodeDecode(p);
}
for(int t=0;t<20;t++)
Console.Write(b[t]);
Console.WriteLine();
}
unsafe public static void NEncodeDecode(char *s)
{
int w;
for(int y=0;y<20;y++)
{
w=(int)*(s+y);
w=w^5;
*(s+y)=(char)w;
}
}
}
This is the output.
the original string : Code Project is cool the encoded string : Fja`%Uwjo`fq%lv%fjji the decoded string : Code Project is cool
You will notice a new keyword here called fixed. When you
precede a statement or a function with fixed you are instructing
the .Net garbage collector not to relocate that variable till the statement or
function has finished. The fixed keyword is only allowed in an
unsafe context. If we don't use fixed there is little point in
using pointers as the results would be unpredictable if the garbage collector
keeps relocating the managed variables. Luckily the compiler won't let you point
to managed variables unless you specify the fixed keyword.
In the function you can see that I use the expression *(s+y). s is the
address pointing to the string. y is incremented starting from 0 and ending upto
19. Thus when I give *(s+y) I get the pointers to characters in those locations.
Lets assume s points to 1000. Thus *(s) will give me the contents of location
1000. Now if I give *(s+1) I get the contents of 1002, and for *(s+2) I get 1004
and so on. The compiler knows I am pointing to a character array and thus each
increment jumps 2 bytes as char is a 16 bit value. C# actually maps char to the
.Net type System.Char.
Conclusion
Please be careful when writing unsafe code. Any small error, even a silly
typing mistake, might crash your program randomly and unpredictably. The error
might also be a rarely occurring one and thus harder to debug. But those of you
who had used pointers in C/C++ and want to use them in C# may do so at their
leisure.