(*) Unsafe and fixed
Unsafe
{
Int [] array = new int [10];
For (int I = 0; I <array. Length; I ++)
{
Array [I] = I;
}
Fixed (int * p = array)
{
For (int I = 0; I <array. Length; I ++)
{
System. Console. WriteLine (p [I]);
}
}
}
Pointers are not recommended in c #, and pointer operations are considered unsafe ). Therefore, before running this code, you must change it to another place. Otherwise, the Code cannot be compiled.
Modify method: Find your project in solution Explorer on the right, right-click the project icon (green), select the last properties, and select Allow unsafe code on the Build tab. Then this code can run. You will see that the above Code can manipulate the array with pointers like the C language. The premise is that there must be fixed (int * p = array), which means that p is fixed to the array and cannot be modified. Because the automatic garbage collection mechanism of C # will allow the allocated inner to adjust the position during running, if so, p may start with array, however, after the location of array is adjusted to another location, p points to no array. Therefore, you need to add a fixed keyword and place it there, so that subsequent operations will be guaranteed.
Note the following:
1) the pointer must be used in the unsafe area. The unsafe keyword can also be used as a modifier for classes or methods.
2) In fixed (int * p = array), the definition of p cannot be written elsewhere, and the fixed keyword can only be used in the unsafe area.
(*) A concise unsafe statement
Class Program
{
Unsafe public static UInt16 Htons (UInt16 src)
{
UInt16 dest;
// The source code of C cannot be copied, because some types have different lengths, such as char (2 bytes) and long (8 bytes)
// (Char *) & dest) [0] = (char *) & src) [1];
// (Char *) & dest) [1] = (char *) & src) [0];
(Byte *) & dest) [0] = (byte *) & src) [1];
(Byte *) & dest) [1] = (byte *) & src) [0];
Return dest;
}
Public static UInt16 ConciseHtons (UInt16 src)
{
UInt16 dest;
Unsafe
{
(Byte *) & dest) [0] = (byte *) & src) [1];
(Byte *) & dest) [1] = (byte *) & src) [0];
}
Return dest;
}
Static void Main ()
{
UInt16 val = 1;
// If the method is unsafe, it must be called in the unsafe block.
Unsafe
{
Val = Htons (val );
}
Console. WriteLine (val );
// Write the unsafe block in the function.
Val = ConciseHtons (val );
Console. WriteLine (val );
}
}
(*) Stackalloc
Stackalloc is used only to allocate arrays to the stack (by default, it is allocated to the managed stack ).
Class MyClass
{
Public int val;
}
Class Program
{
Static void Main ()
{
Unsafe
{
MyClass * p = stackalloc MyClass [1]; // Error !! If the type is to be placed on the managed stack, it won't work. If MyClass is struct, it will be OK.
P-> val = 1;
Int * iArray = stackalloc int [100]; // OK, create an array on the stack. The int type itself is placed on the stack.
}
}
}
Note: The memory to which the pointer points must be fixed. All the reference types in C # (all types of arrays are reference types) are allocated on the managed stack and are not fixed. There are two ways to force fixation: one is to use stackalloc to allocate on the stack, and the other is to use fixed to allocate on the stack.