C# Unsafe code
When a code block usesunsafeWhen marked with the modifier, C# allows the use of pointer variables in functions.Unsafe codeor unmanaged code refers to the use ofPointerVariable code block.
Pointer variables
PointerA pointer is a variable whose value is the address of another variable, that is, the direct address of a memory location. Like other variables or constants, you must declare a pointer before you can use it to store the address of another variable.
The general form of a pointer variable declaration is:
type* var-name;
Below is an example of pointer type declaration:
| Example | Description |
|---|---|
int* p |
pis a pointer to an integer. |
double* p |
pIt is a pointer to a double-precision number. |
float* p |
pis a pointer to a floating-point number. |
int** p |
pis a pointer to a pointer to an integer. |
int*[] p |
pis a one-dimensional array of pointers to integers. |
char* p |
pis a pointer to a character. |
void* p |
pIt is a pointer to an unknown type. |
When declaring multiple pointers in the same declaration, 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; // 正确 int *p1, *p2, *p3; // 错误
The following example illustrates the use ofunsafepointers in C# when the modifier is used:
Example
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 results:
Data is: 20 Address is: 99215364
You can also avoid declaring the entire method as unsafe code, and only need to declare part of the method as unsafe code. The following example illustrates this.
Using Pointers to Retrieve Data Values
You can useToString()A method retrieves the data stored at the location referenced by the pointer variable. The following example demonstrates this:
Example
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 results:
Data is: 20 Data is: 20 Address is: 77128984
Passing Pointers as Method Parameters
You can pass pointer variables to a method as parameters. The following example illustrates this:
Example
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 results:
Before Swap: var1: 10, var2: 20 After Swap: var1: 20, var2: 10
Using Pointers to Access Array Elements
In C#, an array name and a pointer to the same data type as the array data 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, as we normally do in C or C++, thefixedkeyword to fix the pointer.
The following example demonstrates this:
Example
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[] list = {10, 100, 200};
fixed(int *ptr = list)
/* Display the array address 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 results:
Address of list[0] = 31627168 Value of list[0] = 10 Address of list[1] = 31627172 Value of list[1] = 100 Address of list[2] = 31627176 Value of list[2] = 200
Compiling unsafe code
To compile unsafe code, you must switch to the command-line compiler and specify/unsafeCommand line.
For example, to compile a program named prog1.cs that contains unsafe code, you need to enter the command on 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.
Steps:
- Open by double-clicking the Properties node in Solution Explorer.Project properties (project properties)。
- ClickBuildTab.
- Select option"Allow unsafe code"。