0% found this document useful (0 votes)
46 views13 pages

Pointers and Low-Level Programming

The document discusses pointers and low-level programming in C#. It covers pointer types, unsafe code, using pointers for dereferencing and address arithmetic, type casts on pointers, pinned and unpinned variables, the address operator, the fixed statement, and examples and dangers of pointer processing.

Uploaded by

api-3734769
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views13 pages

Pointers and Low-Level Programming

The document discusses pointers and low-level programming in C#. It covers pointer types, unsafe code, using pointers for dereferencing and address arithmetic, type casts on pointers, pinned and unpinned variables, the address operator, the fixed statement, and examples and dangers of pointer processing.

Uploaded by

api-3734769
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 13

Pointers

and Low-Level Programming

© University of Linz, Institute for System Software, 2004


published under the Microsoft Curriculum License
1
Pointer Types
Examples
ip int
int* ip; // pointer to an int cell
sp
MyStruct* sp; // pointer to a MyStruct object MyStruct
void* vp; // pointer to any memory location vp
int** ipp; // pointer to a pointer to an int cell
ipp

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)

• must be enclosed in an unsafe block or an unsafe method

unsafe { unsafe void foo() {


int* p; int* p;
... ...
} }

• must be compiled with the unsafe option

csc -unsafe MyProg.cs

• system administrator must assign FullTrust rights to the program

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

Access to struct fields


b
struct Block { int x, y, z; } bp x bp->x = 1; // pointer notation
Block b; y (*bp).y = 2 // alternatively
Block* bp = &b; z
• bp must be of type Block*
• works also for method calls

Access to array elements


a
int[] a = new int[3]; ap 0 ap[0] = 1; // array notation
int* ap = a; 1 *(ap+1) = 2 // alternatively
2
• no index bound checks!
works only in
ap[3] would be accepted
"fixed" statement
4
Address Arithmetic
Pointers can be used in calculations
T
T* p = ...;

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

No pointer arithmetic with void*

5
Type Casts On Pointers
int i;
int* ip;
Block* bp;
void* vp;

Implicit Casts Explicit Casts


(without cast operator) (with cast operator)

T* ⇐ null ip = null; T1* ⇔ T2* ip = (int*)vp; unchecked!


bp = null; vp = (void*)ip;
vp = null; bp = (Block*)vp;

void* ⇐ T* vp = ip; T* ⇔ intType ip = (int*)i;


vp = bp; bp = (Block*)i;
vp = (void*)i;
i = (int)ip;
i = (int)bp;
i = (int)vp;

6
Pinned and Unpinned Variables
Pinned cannot be moved by the garbage collector
• local variables
• value parameters
• fields of pinned structs

Unpinned can be moved by the garbage collector


• fields of classes (also static fields)
• array elements
• ref and out parameters

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

| StringVar • char* must be assignable to PointerType


).
Examples
int field; fixed (int* p = &field) { ... }
int[] a = new int[10]; fixed (int* p = &a[1]) {...}
Person person = new Person(); fixed (int* p = &person.id) {...}
string s = "Hello"; fixed (int* p = a) {...}
fixed (char* p = s) {...}

Variables that are declared in the header of a fixed statement


9
are read-only
Examples
Printing the bytes of an int variable
x
int x = 3;
3 0 0 0
unsafe {
byte* p = (byte*) &x; p
for (int i = 0; i < 4; i++) { Console.Write("{0:x2} ", *p); p++; }
}

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;
}

static unsafe void Main() {


int* p = Foo();
...
*p = 5; // accesses non-existing local variable!
}

Therefore
Avoid pointer processing!
Unless you really need it for system-level programming

13

You might also like