Академический Документы
Профессиональный Документы
Культура Документы
int
Syntax
PointerType = UnmanagedType "*" pointers to arbitrary types
| "void" "*".
UnmanagedType = ValueType if a struct type, all fields must be of an
| PointerType. UnmanagedType
• pointers are not traced by the garbage collector (referenced objects are not collected)
• pointer types are not compatible with System.Object
• pointer variables can have the value null
• pointers of different types can be compared with each other (==, !=, <, <=, >, >=)
2
Unsafe Code
Code that works with pointers is potentially unsafe
(can break type rules and destroy arbitrary memory locations)
3
Using Pointers
Dereferencing a pointer
var
int var; ip *ip = 5;
int* ip = &var; int x = *ip;
• if v is of type T*, *v is of type T
• void* cannot be dereferenced
T T
p++; // increases p by sizeof(T)
p--;
p
T T T
T* q, r;
q = p + 2; // q = p + 2*sizeof(T)
r = p - 1; // r = p - sizeof(T)
r p q
5
Type Casts On Pointers
int i;
int* ip;
Block* bp;
void* vp;
6
Pinned and Unpinned Variables
Pinned cannot be moved by the garbage collector
• local variables
• value parameters
• fields of pinned structs
7
Adress Operator
&designator yields the address of designator
Note
• designator must denote a pinned variable (e.g. &x, &s.f)
• the type of the variable must be unmanaged (i.e. no class, no array)
• if designator is of type T, &designator is of type T*
8
fixed Statement
Pins an unpinned variable during the execution of this statement
(i.e. the garbage collector cannot move it during this statement)
Syntax
FixedStat = "fixed" "(" PointerType FixedVarDecl {"," FixedVarDecl} ")" Statement.
FixedVarDecl = ident "="
( "&" UnpinnedVar • UnpinnedVar must be of an unmanaged type T
• T* must be assignable to PointerType
| ArrayVar • array elements must be of an unmanaged type T
• T* must be asignable to PointerType
String processing
s
string s = "Hello";
H e l l o \0
unsafe {
fixed (char* p = s) { p
for (int i = 0; p[i] != '\0'; i++) Console.Write(p[i]);
}
}
10
Examples (continued)
Overlaying a byte array with a struct type
struct Block {
int x;
float f;
int y;
}
...
byte[] buffer = new byte[1024];
...
unsafe {
fixed (byte* bp = &buffer[3]) {
Block* b = (Block*) bp;
Console.WriteLine(b->x + " " + b->f + " " + b->y);
}
}
x f y
buffer
11
Dangers of Pointer Processing
Can destroy arbitrary memory locations
int[] a = new int[3];
unsafe {
fixed (int* p = a) { p[5] = 0; }
}
One can be left with pointers to objects that are moved by the garbage collector
int[] a = new int[5];
unsafe { q p
int* p;
fixed (int* q = a) { p = q + 2; } a
...
... // GC can move the array now
*p = 5; // destroys data
} p
12
Dangers of Pointer Processing (cont.)
One can be left with pointers to non-existing local variables
static unsafe int* Foo() {
int local = 3;
return &local;
}
Therefore
Avoid pointer processing!
Unless you really need it for system-level programming
13