Tuesday, March 31, 2009

Pointers & Unsafe Myth



This is about ‘Unsafe Code’.


-          C# is very good at hiding much of the basic memory management from the developer.

-          However, there are cases in which you will want direct access to memory. For example, you might want to access a function in an external (non-.NET) DLL that requires a pointer to be passed as a parameter (as many Windows API functions do), or possibly for Performance Reasons.

-          C#’s facilities the direct access to the contents of memory using – Pointers.



Pointers –


-          A pointer is simply a variable that stores the address of something else in the same way as a reference.

-          On the other hand using references in C# is also a type-safe pointer.

-          The difference is that C# does not allow you direct access to the address contained in a reference variable. With a reference, the variable is treated syntactically as if it stores the actual contents of the referent.


-          C# references prevent you from inadvertently doing something that corrupts the contents of memory.

-          With a pointer, on the other hand, the actual memory address is available to you. This gives you a lot of power to perform new kinds of operations.


However there are two main reasons for using pointers:


-          Backwards compatibility


§                     Despite all of the facilities provided by the .NET runtime, it is still possible to call native Windows API functions, and for some operations, this may be the only way to accomplish your task.

§                     These API functions are generally written in C and often require pointers as parameters.

§                     However, in many cases it is possible to write the DllImport declaration in a way that avoids use of pointers, for example, by using the System.IntPtr class.


-          Optimized Performance


§                     On those occasions where speed is of the utmost importance, Pointers Can Provide A Route To Optimized Performance.

§                     Provided you know what you are doing, you can ensure that data is accessed or manipulated in the most efficient way.



Pointer Hiccups –


-          Low-level memory access comes at a price. The syntax for using pointers is more complex than that for reference types and pointers are unquestionably more difficult to use correctly.

-          You need good programming skills and an excellent ability to think carefully and logically about what your code is doing in order to use pointers successfully.

-          If you are not careful, it is very easy to introduce subtle, difficult to find bugs into your program using pointers. For e.g.

§                     Overwrite other variables,

§                     Cause stack overflows,

§                     Access areas of memory that don’t store any variables, or

§                     Even overwrite information about your code that is needed by the .NET runtime, thereby crashing your program.


-          In addition, if you use pointers your code must be granted a high level of trust by the code access security mechanism or it will not be allowed to execute.

-          Under the default code access security policy, this is only possible if your code is running on the local machine.

-           If your code must be run from a remote location, such as the Internet, users must grant your code additional permissions for it to work.



Unsafe Block –


-          Due to the risks associated with pointers, C# only allows the use of pointers in blocks of code that you have specifically marked for this purpose using ‘unsafe’ keyword.

-          Otherwise it produces error while compiling.

-          Once you have any ‘unsafe’ code, the application will not compile in normal fashion. To compile either you have to use the /unsafe switch or check the checkbox which allows unsafe code in your application using ‘Project Properties’ dialog.


csc /unsafe MySource.cs

csc -unsafe MySource.cs


You can mark an Individual Method as being unsafe like this:

unsafe int GetSomeNumber()


// code that can use pointers



You can also mark an Entire Class Or Struct as unsafe, which means that all of its members are assumed to be unsafe:

unsafe class MyClass


// any method in this class can now use pointers



You can mark a Member as unsafe:

class MyClass


  unsafe int *pX; // declaration of a pointer field in a class




You can mark a Block Of Code within a method as unsafe:

void MyMethod()


// code that doesn’t use pointers



// unsafe code that uses pointers here


// more ‘safe’ code that doesn’t use pointers



You cannot mark a local variable by itself as unsafe:

int MyMethod()


 unsafe int *pX; // WRONG



Hope this helps.



Arun Manglick

No comments:

Post a Comment