C# can do direct memory manipulation via pointers within blocks of code marked unsafe.
The unsafe code should be compiled with the /unsafe
compiler option.
A pointer instance holds the address of a variable.
Pointer types can be cast to any other pointer type.
The main pointer operators are:
Operator | Meaning |
---|---|
& | returns a pointer to the address of a variable |
* | returns the variable at the address of a pointer |
-> | a syntactic shortcut, in which x->y is equivalent to (*x).y |
By marking a type, type member, or statement block with the unsafe
keyword, we can
use pointer types and perform C++ style pointer operations on memory.
Here is an example of using pointers to quickly process an array:
unsafe void Process (int[,] data){
int length = data.Length;
fixed (int* b = data){
int* p = b;
for (int i = 0; i < length; i++)
*p++ &= 0xFF;
}
}
Within a fixed
statement, we can get a pointer to any value type, an array of value
types, or a string.
In the case of arrays and strings, the pointer will actually point to the first element, which is a value type.
Value types declared inline within reference types require the reference type to be pinned, as follows:
class Main {//from ww w . j a v a2s . c o m
int x;
static void Main(){
Test test = new Test();
unsafe{
fixed (int* p = &test.x) // Pins test
{
*p = 0;
}
System.Console.WriteLine (test.x);
}
}
}
In addition to the &
and *
operators,
C# also provides the C++ style ->
operator,
which can be used on structs:
struct Test{
int x;
unsafe static void Main(){
Test test = new Test();
Test* p = &test;
p->x = 1;
System.Console.WriteLine (test.x);
}
}