Prizes & Awards
My Profile
Active Members
TodayLast 7 Days
more...
|
Resources » Articles » .NET Framework »
Pointers in C# and writing Unsafe code
|
Together, unsafe code and pointers enable C# to be used to create applications that you might normally associate with C++: high-performance, systems code. Moreover, the inclusion of unsafe code and pointers gives C# capabilities that are lacking in Java.
Managed Code
In general, when you write a C# program, you are creating what is called managed code. Managed Code is executed under the control of the Common Language Runtime.
Unsafe Code
C# allows you to write what is called “unsafe” code. While this statement might seem shocking, it really isn’t. Unsafe code is not code that is poorly written; it is code that does not execute under the full management of the Common Language Runtime (CLR). The code is called “unsafe” because it is not possible to verify that it won’t perform some type of harmful action.
Given that unsafe code might cause problems, you might ask why anyone would want to create such code. The answer is that managed code prevents the use of pointers. Since a pointer can point anywhere in the memory, it is possible to misuse a pointer. It is also easy to introduce a coding error when using pointers. This is why C# does not support pointers when creating managed code. Pointers are however, both useful and necessary for some types of programming (such as system-level utilities), and C# does allow you to create and use pointers. All pointer operations must be marked as unsafe, since they execute outside the managed context.
Note: To compile unmanaged code, you must use the /unsafe compiler option.
Pointer Basics
Pointers are variables that hold the addresses of other variables. For example, if x contains the address of y, then x is said to “point to” y. Once a pointer points to a variable, the value of that variable can be obtained or changed through the pointer. Operations through pointers are often referred to as indirection.
Declaring a Pointer
The general form of a pointer variable declaration is:
type* var-name;
Here, type is the pointer’s base type, which must be a nonreferance type. Thus you cannot declare a pointer to a class object. Notice the placement of the *. It follows the type name. var-name is the name of the pointer variable. To declare ip to be a pointer to an int, use this declaration:
int* ip;
In general, in a declaration statement, following a type name with a * creates a pointer type. In C#, the * is distributive and the declaration:
int* p, q;
creates two pointer variables.
The * and & Pointer Operators
Two operators are used with pointers: * and &. The & is a unary operator that returns the memory address of its operand. For example,
int* ip; int num = 10;
ip = #
put’s into ip the memory address of the variable num. This address is the location of the variable in the computers internal memory. It has nothing to do with the value of num. thus ip does not contain the value 10.It contains the address at which num is stored. The operation of & can be remembered as returning “the address of” the variable it precedes.
The second operator is *, and it is the compliment of &. It is a unary operator that refers to the value of the variable located at the address specified by its operand. So,
int val = *ip;
will place into val the value 10. The operation of * can be remembered as “at address.”
The * can also be used on the left side of an assignment statement. For example,
*ip = 100;
Thus, This statement can be read as “at address ip, put the value as 100.”
Using unsafe
Any code that uses pointers must be marked as unsafe by using the unsafe keyword. You can mark an individual statement or an entire method unsafe. For example here is a program that uses pointers inside Main(), which is marked unsafe:
//Demonstrate pointers and unsafe. using System; class UnsafeCode { //mark main as unsafe unsafe public static void Main() { int count = 99; int* pointer; //create an int pointer. pointer = &count; //put address of count into pointer
Console.WriteLine( "Initial value of count is " + *pointer ); *pointer = 10; //assign 10 to count via pointer Console.WriteLine( "New value of count is " + *pointer); Console.ReadLine(); } }
The output of this program is shown here:
Initial value of count is 99 New Value of count is 10
Using fixed
The fixed modifier is often used when working with pointers. It prevents a managed variable from being moved by the garbage collector. This is needed when a pointer refers to a field in a class object, for example. Since the pointer has no knowledge of the actions of the garbage collector, if the object is moved, the pointer will point to the wrong object. Here is a general form of fixed:
fixed ( type* p = &var ) { // use fixed object }
Here, p is a pointer that is being assigned the address of a variable. The object will remain at its current memory location until the block of code has executed. The fixed keyword can be used only in an unsafe context. You can declare more than one fixed pointer at a time using a comma-separated list. Here is an example of fixed:
//Demonstrate fixed. using System; class Test { public int number; public Test(int i) { number = i; } } class FixedCode { //mark as unsafe unsafe public static void Main() { Test test=new Test(19); fixed ( int* pointer = &test.number) { //use fixed to put address of test.num into pointer Console.WriteLine( "Initial value of test.number is " + *pointer); *pointer = 10; //assign to count via pointer Console.WriteLine( "New value of test.number is " + *pointer); Console.Read(); } } }
The output from this program is shown here:
Initial value of test.number is 19 New value of test.number is 10
Here, fixed prevents test from being moved. Because pointer points to test.number, if test were moved, then pointer would point to an invalid location.
|
Responses
|
| Author: Thomas Herring 05 Aug 2004 | Member Level: Bronze Points : 0 | I am a C++ programmer learning C#. This is a great bit of knowlege for me as I am having trouble manipulating objects as I am used to.
Thank you.
| | Author: Peter Goodsall 21 Nov 2004 | Member Level: Bronze Points : 0 | This is so useful! Thanks - I too am new to C#, coming from a background in C++, and was a little alarmed on first coming across the term "Unsafe Code"!
| | Author: Subhashini Janakiraman 01 Jan 2008 | Member Level: Silver Points : 0 | The tutorial is simple and elegant.It gives a brief summary of pointers.Useful for beginners.
|
|