YouTip LogoYouTip

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**".
← Csharp MultithreadingCsharp Anonymous Methods β†’