Csharp Unsafe Codes
When a code block is marked with the **unsafe** modifier, C# allows the use of pointer variables within functions. **Unsafe code** or unmanaged code refers to code blocks that use **pointer** variables.
A **pointer** is a variable whose value is the address of another variable, i.e., the direct address of a memory location. Like any other variable or constant, you must declare a pointer before you use it to store the address of another variable.
The general form of a pointer variable declaration is:
type* var-name;
Here are examples of pointer type declarations:
| Example | Description |
| --- | --- |
| `int* p` | `p` is a pointer to an integer. |
| `double* p` | `p` is a pointer to a double. |
| `float* p` | `p` is a pointer to a float. |
| `int** p` | `p` is a pointer to a pointer to an integer. |
| `int*[] p` | `p` is a one-dimensional array of pointers to integers. |
| `char* p` | `p` is a pointer to a character. |
| `void* p` | `p` is a pointer to an unknown type. |
When declaring multiple pointers in a single statement, the asterisk * is written only with the base type; it is not used as a prefix for each pointer name. For example:
int* p1, p2, p3; // Correct int *p1, *p2, *p3; // Incorrect
The following example illustrates the use of pointers in C# when the **unsafe** modifier is used:
## Example
using System;
namespace UnsafeCodeApplication
{
class Program
{
static unsafe void Main(string[] args)
{
int var=20;
int* p =&var;
Console.WriteLine("Data is: {0} ", var);
Console.WriteLine("Address is: {0}", (int)p);
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
Data is: 20Address is: 99215364
You can also declare only a part of a method as unsafe, rather than the entire method. The following example demonstrates this.
You can use the **ToString()** method to retrieve the data stored at the location referenced by the pointer variable. The following example demonstrates this:
## Example
using System;
namespace UnsafeCodeApplication
{
class Program
{
public static void Main()
{
unsafe
{
int var=20;
int* p =&var;
Console.WriteLine("Data is: {0} " , var);
Console.WriteLine("Data is: {0} " , p->ToString());
Console.WriteLine("Address is: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
Data is: 20Data is: 20Address is: 77128984
You can pass pointer variables as parameters to methods. The following example demonstrates this:
## Example
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe void swap(int* p, int*q)
{
int temp =*p;
*p =*q;
*q = temp;
}
public unsafe static void Main()
{
TestPointer p =new TestPointer();
int var1 =10;
int var2 =20;
int* x =&var1;
int* y =&var2;
Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
Before Swap: var1: 10, var2: 20After Swap: var1: 20, var2: 10
In C#, an array name and a pointer to a data type of the same data type are different variable types. For example, `int *p` and `int[] p` are different types. You can increment the pointer variable `p` because it is not fixed in memory, but the array address is fixed in memory, so you cannot increment the array `p`.
Therefore, if you need to use a pointer variable to access array data, you can use the **fixed** keyword to fix the pointer, as we typically do in C or C++.
The following example demonstrates this:
## Example
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[]list ={10, 100, 200};
fixed(int*ptr = list)
/* Display the address of the array in the pointer */
for(int i =0; i <3; i++)
{
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
Address of list = 31627168Value of list = 10Address of list = 31627172Value of list = 100Address of list = 31627176Value of list = 200
To compile unsafe code, you must switch to the command-line compiler and specify the **/unsafe** command-line option.
For example, to compile a program named `prog1.cs` that contains unsafe code, you would enter the following command at the command line:
csc /unsafe prog1.cs
If you are using the Visual Studio IDE, you need to enable unsafe code in the project properties.
The steps are as follows:
* Open the **project properties** by double-clicking the **properties** node in the Solution Explorer.
* Click the **Build** tab.
* Select the option "**Allow unsafe code**".
YouTip