pointers in c - university of birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · in c++, it is...

153
Pointers in C Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/ ~ hxt February 2, 2017 Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/ ~ hxt 1

Upload: dangdieu

Post on 04-Jun-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointers in C

Hayo ThieleckeUniversity of Birmingham

http://www.cs.bham.ac.uk/~hxt

February 2, 2017

••

••

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 1

Page 2: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Intro to pointers

Pointer definitions and examples

Pointer equality in C

Memory management with malloc and free

Memory errors

Valgrind detects memory errors and leaks

Structures and pointers ⇒ recursive data structures

Pointer arithmetic and arrays

Strings and buffer overflows

Void pointers and casting

Function pointers

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 2

Page 3: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Outline of pointers in C part of the module

Pointers are the fundamental new feature of C compared to thelanguages you have been taught previously.Pointers are everywhere in C:

1. pointer types and operations

2. pointer equality

3. malloc and free

4. structures and pointers

5. pointer arithmetic

6. strings and pointers

7. function pointers

Syntax:

* & = == malloc free struct . -> ++ -- (*f)()

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 3

Page 4: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Back to basics: what is the meaning of =

What is the meaning of:

x = x + 1;

Does it mean: revolutionary new result in algebra:Like, every number is equal to the next biggest number?

2 = 2 + 1

No so much.Basic imperative programming: abstraction of the memory asnamed boxes that contain values.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 4

Page 5: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Back to basics: what is the meaning of =

What is the meaning of:

x = x + 1;

Does it mean: revolutionary new result in algebra:Like, every number is equal to the next biggest number?

2 = 2 + 1

No so much.Basic imperative programming: abstraction of the memory asnamed boxes that contain values.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 5

Page 6: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

L and R values in C

What is the meaning of:

x = x + 1;

before:2x

after:3x

The x on the left of the = refers to the address (L-value) of x.The x on the right of the = refers to the contents (R-value) of x.In C, L-values are particularly important, in the form of pointers.•p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 6

Page 7: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

L and R values in C

What is the meaning of:

x = x + 1;

before:2x

after:3x

The x on the left of the = refers to the address (L-value) of x.The x on the right of the = refers to the contents (R-value) of x.In C, L-values are particularly important, in the form of pointers.•p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 7

Page 8: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

L and R values in C

What is the meaning of:

x = x + 1;

before:2x

after:3x

The x on the left of the = refers to the address (L-value) of x.The x on the right of the = refers to the contents (R-value) of x.In C, L-values are particularly important, in the form of pointers.•p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 8

Page 9: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

L and R values in C

What is the meaning of:

x = x + 1;

before:2x

after:3x

The x on the left of the = refers to the address (L-value) of x.The x on the right of the = refers to the contents (R-value) of x.In C, L-values are particularly important, in the form of pointers.•p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 9

Page 10: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointers are an abstraction of machine addresses

A box-and-arrow diagram•p

represents at the hardware levelnp n

for some memory address n.But in C, we are not supposed to care about actual hardwareaddresses.The view in C of memory is a graph:nodes = chunks of memory (often a struct)edges = pointersThat is why box-and-arrow diagrams are so useful.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 10

Page 11: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Why pointers are hard for everybody

I Pointers are hard because they are non-local

I imperative programming without pointers (like Basic/Fortran):x = 2; y = y + 1;The assignment to x does not change the value of y, andconversely.

I A graph that changes non-locally.

I The same issues arise in Java with references between objects.

I They may be obscured by Java bureaucracy.

I Pointers in C/C++ are made even harder by the need tomanage memory.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 11

Page 12: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointers and current research

I Pointers have been around for a long time, but have oftenbeen considered incomprehensible

I Since about 2000, there has been a huge amount of researchon pointers, particularly Separation Logic.⇒ Program analysis tools in industry, e.g. Microsoft andFacebook (Infer).

I LLVM/clang comes with a static analyzer that can detect(some!) pointer bugs

I We will use Valgrind

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 12

Page 13: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointers and pointer type in C: the * operator

I In C, * is also a unary operator.

I It has nothing to do with the binary infix operator formultiplication, even though it uses the same character.

I If P is an expression denoting a pointer, then *P is the resultof dereferencing the pointer.

I If T is a type, then T *p; declares p to be of type “pointer toT”

I If T is a type, then T* is the type of pointers to something oftype T. This is used for example in casting.

I pointer = programming abstraction of machine address inmain memory

I dereferencing = load value from memory

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 13

Page 14: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

The address operator & in C

I If a variable appears on the right-hand side of an =, itsR-value is taken.

I If we want the address of x rather than its contents, we usethe & operator, as in &x

I y = x; means y gets the contents of x

I p = &x; means p is made to point to x

I Quiz: what is *&x

I Note: in C++ & also used as the type constructor forreferences, e.g. int&.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 14

Page 15: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

x

p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 15

Page 16: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

x

p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 16

Page 17: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

5x

p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 17

Page 18: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

5x

•p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 18

Page 19: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

5x

•p1 •p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 19

Page 20: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example: *, &, and aliasing

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What is the value of x at the end?

6x

•p1 •p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 20

Page 21: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer example - how not to think

int x;

int *p1;

int *p2;

x = 5;

p1 = &x;

p2 = p1;

(*p2)++;

What about this reasoning:x = 5p1 = 5p2 = 5p2 updated, sop2 = 6Hence x is 5 at the end.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 21

Page 22: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer == in C

In C, two pointers are == if they refer to the same address inmemory.Pointer equality is different from structural equality like that builtinto functional languages, e.g., in OCaml:

# [ 1 ] = [ 1 ];;

- : bool = true

p = q makes p == q

*p = *q does not make p == q

In C++, you can overload ==.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 22

Page 23: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Null pointer

There is a special pointer value, the null pointerIn C, it is called NULL

In C++, it is called nullptr

The null pointer does not point to anythingDereferencing NULL gives undefined behaviour (usually crash)Typical idiom: test whether a pointer p is equal to the null pointer:

if (p) ...

Note: pointers are not always initialized to null

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 23

Page 24: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer equality example 1

7

•p1

7

•p2

True or false?

p1 == p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 24

Page 25: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer equality example 2

8

•p1

8

•p2

True or false?

*p1 == *p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 25

Page 26: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer equality example 3

7

•p1

7

•p2

True or false?

p1 == p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 26

Page 27: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer equality example 4

NULL

•p1

•p2

True or false?

p1 == *p2

p2 == NULL

p1 == NULL

**p2 == NULL

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 27

Page 28: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Write Java code that shows the same issues as the previous pointerdiagrams, in terms of aliasing, update, and equality.In Java, you need to use object references instead of pointers.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 28

Page 29: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer type and declaration syntax

int *p, n;

is like

int *p;

int n;

and not

int *p;

int *n;

Pitfall: The * sticks only to the p and not the int.That is why I don’t write int* p; .Array declarations behave the same, sticking only to one identifier.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 29

Page 30: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Quiz

What are the types?

float **q, *p, a[], f;

What is wrong with this:

int *p, n;

p = n;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 30

Page 31: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Suppose

int *p1, *p2l

Explain the difference between

p1 = p2;

and

*p1 = *p2;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 31

Page 32: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

int x, y, *p1, *p2, **q1, **q2;

x = 10;

y = 20;

p1 = &x;

q1 = &p2;

q2 = q1;

*q2 = p1;

(**q1) = 7;

What is the value of x at the end? Draw the memory with thepointers as arrows.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 32

Page 33: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Memory management withmalloc and free

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 33

Page 34: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free from stdlib

I stdlib.h provides C functions malloc and free

I The part of memory managed by malloc is called the heap.

I malloc: you borrow some memory from the memory manager

I free: you give back the memory and promise not to touch itagain

I The memory manager cannot force you to keep that promise;it is up to you

I if you use memory incorrectly in C, you get undefinedbehaviour

I malloc and free are not part of the C language itself, only itsstandard library

I You could implement your own malloc and free in C

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 34

Page 35: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free

The function malloc borrows some uninitialized memory in theheap from the memory allocator.

before:p

p = malloc(N);

after:•p N bytes

The function free gives memory back to the memory allocator.

before: •p

free(p);

after: •p

The call to free changes the ownership of the memory, not p orother pointers to it.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 35

Page 36: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free

The function malloc borrows some uninitialized memory in theheap from the memory allocator.

before:p

p = malloc(N);

after:•p N bytes

The function free gives memory back to the memory allocator.

before: •p

free(p);

after: •p

The call to free changes the ownership of the memory, not p orother pointers to it.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 36

Page 37: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free

The function malloc borrows some uninitialized memory in theheap from the memory allocator.

before:p

p = malloc(N);

after:•p N bytes

The function free gives memory back to the memory allocator.

before: •p

free(p);

after: •p

The call to free changes the ownership of the memory, not p orother pointers to it.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 37

Page 38: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free

The function malloc borrows some uninitialized memory in theheap from the memory allocator.

before:p

p = malloc(N);

after:•p N bytes

The function free gives memory back to the memory allocator.

before: •p

free(p);

after: •p

The call to free changes the ownership of the memory, not p orother pointers to it.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 38

Page 39: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Memory after freeing

After free(p), the memory is no longer owned by the program.•p

Dereferencing p causes undefined behaviourThe program may crash, or anything at all may happen, such asmemory changing its content in unpredicatable ways.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 39

Page 40: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free internally

A memory allocator could be implemented in C as follows:

I The allocator requests some memory from the OS (via sbrk inUnix)

I The available memory is divided into chunks that are linkedtogether in a “free list”

I malloc detaches a chunk from the free list and returns apointer to it

I free takes a pointer to a chunk and links it into the free listagain

I problems: efficiency, memory fragmentation

I a naive allocator is in K&R

I Doug Lea’s malloc is more sophisticated:http://g.oswego.edu/dl/html/malloc.html

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 40

Page 41: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

How to think of deallocation

After free is called on some memory, various things may actuallyhappen.

I The same piece of memory is re-used in a later malloc.

I The memory manager writes its own data structures into thememory (e.g. free list).

Rather than trying to guess what exactly happens, we call all ofthis undefined behaviour.C (unlike Java) does not prevent you from doing bad things.You can still access the memory but should not.One could think of the memory as “cursed”, so to speak.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 41

Page 42: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

sizeof operator

I For using malloc, we need to the function how many bytes toallocate.

I Usually enough to hold value of some type.

I But sizes are implementation dependent.

I The compiler tells us how big it makes each type.

I sizeof(T) gives the size in bytes for some type T.

I Hence the idiom

T *p = malloc(sizeof(T))

for some type T.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 42

Page 43: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

calloc and realloc

stdlib.h also contains these variants of malloc:calloc allocate and initialize to zerosrealloc reallocate

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 43

Page 44: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc example

int *p1, **p2;

p1 = malloc(sizeof(int));

*p1 = 7;

p2 = malloc(sizeof(int*));

*p2 = p1;

heap 7

•p1

•p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 44

Page 45: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

malloc and free example

int *p1, **p2;

p1 = malloc(sizeof(int));

*p1 = 7;

p2 = malloc(sizeof(int*));

*p2 = p1;

free(p1);

•p1

•p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 45

Page 46: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

use after free example

int *p1, **p2;

p1 = malloc(sizeof(int));

*p1 = 7;

p2 = malloc(sizeof(int*));

*p2 = p1;

free(p1);

**p2 = 11;

•p1

•p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 46

Page 47: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

double free example

int *p1, **p2;

p1 = malloc(sizeof(int));

*p1 = 7;

p2 = malloc(sizeof(int*));

*p2 = p1;

free(p1);

p1 = NULL;

free(*p2);

NULLp1

•p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 47

Page 48: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Don’t free something that did not come from malloc

int x[10];

void f(int z)

{

int y;

free(x);

free(&y);

free(&z);

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 48

Page 49: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Memory leak example

int *p1, **p2;

p1 = malloc(sizeof(int));

*p1 = 7;

p2 = malloc(sizeof(int*));

*p2 = p1;

p1 = NULL;

p2 = NULL;

7

NULLp1

NULLp2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 49

Page 50: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Draw the memory after the following code has run.int *p1, *p2, **q;

p1 = malloc(sizeof(int));

p2 = malloc(sizeof(int));

q = malloc(sizeof(int*));

*q = p1;

**q = 7;

*q = p2;

free(*q);

free(q);

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 50

Page 51: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

“crash” 6= memory error

I “crash” has many name: core dump, segmentation fault

I error detected by the hardware and OS

I the hardware and OS keep of track of who owns a page ofmemory

I in C, a memory error may lead to a seg fault,it does not have to

I a write error that does not lead to a segfault may corruptmemory, which is even worse

I memory errors lead to undefined behaviour per the C standard

I a C program with a memory error is always wrong

I a memory leak is not the same as a memory error, and notalways as bad

I a memory leak may lead to crash when the programeventually runs out of memory

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 51

Page 52: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Different memory horrors in C

Many students (and not only they) are confused about thedifference between:

I memory error

I memory leak

I segmentation fault or similar error messages from the OS

I buffer overflow (see below)

You need to understand the distinction.Memory errors and leaks are:

I not necessarily observable

I not deterministic

⇒ testing for them becomes very hard

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 52

Page 53: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Memory errors are scary

Page 54: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Valgrind and memcheck

http://valgrind.org

http://valgrind.org/docs/manual/quick-start.html

Valgrind is an instrumentation framework for buildingdynamic analysis tools. There are Valgrind tools that canautomatically detect many memory management andthreading bugs, and profile your programs in detail.

http://valgrind.org/docs/manual/mc-manual.html

In C, the memory does not actually become red or cursed after freeO RLY? YA RLYRather, it becomes nondeterministicValgrind makes the red memory observable and producesdeterministic errorsLikewise for memory leaks⇒ valgrind allows us to test code for memory errors/leaks

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 54

Page 55: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Using clang and valgrind

For background on Memcheck, seehttp://valgrind.org/docs/manual/mc-manual.html.Suppose your program is called frodo.c.Compile with clang:

clang -Wall -o frodo frodo.c

Compile with gcc:

gcc -Wall -o frodo frodo.c

Then use valgrind to run the compiled code:

valgrind --leak-check=full ./frodo

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 55

Page 56: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

use-after-free.c

#include <stdlib.h>

int main()

{

int *p = malloc(sizeof(int));

free(p);

*p = 42;

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 56

Page 57: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Memory error detected by valgrind

wallace% valgrind use-after-free

==7675== Memcheck, a memory error detector

==7675== Copyright (C) 2002-2012, and GNU GPL’d, by Julian Seward et al.

==7675== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info

==7675== Command: use-after-free

==7675==

==7675== Invalid write of size 4

==7675== at 0x40052A: main (in /home/staff/hxt/code/c/valgrind-tests/use-after-free)

==7675== Address 0x4c37040 is 0 bytes inside a block of size 8 free’d

==7675== at 0x4A06430: free (vg_replace_malloc.c:446)

==7675== by 0x400523: main (in /home/staff/hxt/code/c/valgrind-tests/use-after-free)

==7675==

==7675==

==7675== HEAP SUMMARY:

==7675== in use at exit: 0 bytes in 0 blocks

==7675== total heap usage: 1 allocs, 1 frees, 8 bytes allocated

==7675==

==7675== All heap blocks were freed -- no leaks are possible

==7675==

==7675== For counts of detected and suppressed errors, rerun with: -v

==7675== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 57

Page 58: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

leak.c

#include <stdlib.h>

int main()

{

malloc(100);

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 58

Page 59: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Leak detected by valgrind

wallace% valgrind leak

==7769== Memcheck, a memory error detector

==7769== Copyright (C) 2002-2012, and GNU GPL’d, by Julian Seward et al.

==7769== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info

==7769== Command: leak

==7769==

==7769==

==7769== HEAP SUMMARY:

==7769== in use at exit: 100 bytes in 1 blocks

==7769== total heap usage: 1 allocs, 0 frees, 100 bytes allocated

==7769==

==7769== LEAK SUMMARY:

==7769== definitely lost: 100 bytes in 1 blocks

==7769== indirectly lost: 0 bytes in 0 blocks

==7769== possibly lost: 0 bytes in 0 blocks

==7769== still reachable: 0 bytes in 0 blocks

==7769== suppressed: 0 bytes in 0 blocks

==7769== Rerun with --leak-check=full to see details of leaked memory

==7769==

==7769== For counts of detected and suppressed errors, rerun with: -v

==7769== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 59

Page 60: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structures and pointers⇒ recursive data structures

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 60

Page 61: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structures in C

I A structure (or struct) in C is much like a Java class thatcontains only data (no methods)

I C++ jargon: POD for “plain old data”

I evolution: C struct → C++ class → Java class

I Terminology: a structure contains members (not “variables”)

I In C++ (not plain C), you can also define functions inside astruct

I This gives OO, where operations on data are packagedtogether with the data in objects

I In C, functions are defined outside structs and often accessthem via pointers

I Structures and pointers (along with malloc) let us build manyclassic data structures: lists, trees, graphs

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 61

Page 62: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structure syntaxC structure syntax is similar to Java class syntax:

struct s {

T1 m1;

...

Tk mk;

};

Here T1, . . . , Tn are type names.Note the semicolon at the endAfter a structure s has been declared, struct s can be used as atype name.

int n; // declares n as an int

struct s y; // declares y as a struct s

struct s *p; // declares p as a pointer to a struct s

Access to structure member is by using the dot operator, e.g., s.m1

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 62

Page 63: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structure syntax example

struct Point {

int x, y;

};

...

struct Point v;

v.x = v.y;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 63

Page 64: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structure layout in memory

struct S {

T1 m1;

T2 m2;

...

Tk mk;

};

m1

m2...

mk

Structure members are laid out in memory in order.There may be a few bytes of padding between structure membersdue to alignment, depending on the hardware.May get some padding to get the pointer aligned:

struct S {

char c;

char *p;

};

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 64

Page 65: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structure and sizeof

struct S {

T1 m1;

T2 m2;

...

Tk mk;

};

m1

m2...

mk

What is sizeof(struct S)?

sizeof(struct S) ≥ sizeof(T1) + . . . + sizeof(Tk)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 65

Page 66: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structure and sizeof

struct S {

T1 m1;

T2 m2;

...

Tk mk;

};

m1

m2...

mk

What is sizeof(struct S)?

sizeof(struct S) ≥ sizeof(T1) + . . . + sizeof(Tk)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 66

Page 67: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Recursive types from structures and pointersStandard example of recursive data structures: list and trees.

struct IntList {

struct IntList *next;

int data;

};

struct Bintree {

struct BinTree *left, *right;

int data;

};

struct Quadtree {

struct QuadTree *chld[4];

int data;

};

The pointers are required for the recursion.Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 67

Page 68: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

-> operator

I p->m is an abbreviation for (*p).m.

I Dereference pointer, then structure member access.

I Very common in C and C++ code.

I Useful for chaining together:

p->m1->m2->m3

I Also used for OO (member functions) in C++, as in p->f()

I Exercise: write p->x->y->z using only . and *.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 68

Page 69: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

List traversal idiom in C

A pointer p in a condition

while(p) { ... }

is equivalent to

while(p != NULL) { ... }

It is a common idiom for looping over lists, along with anassignment such as

p = p->next;

In modern C++ and Java, one could use iterators for thissituation, but since C does not have an iterator construct, one usesthe idiom above.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 69

Page 70: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A common error in traversing data structures

Many students write things like

T f(struct List *p)

{

while(p->next)

...

}

A linked list could be null: that represents the empty listStart by testing for null pointer

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 70

Page 71: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example: deleting all elements of a linked list

while(lp) {

q = lp;

lp = lp->next;

free(q);

}

Why do we need the extra pointer q? Why not

while(lp) {

free(lp);

lp = lp->next;

}

use after free

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 71

Page 72: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Traversal and recursion vs while

I For lists, a while loop is sufficient to traverse

I A modern C compiler may, but is not required to, compile tailrecursion as efficiently as a while loop.

I For traversing trees and graphs, recursion is much easier toprogram correctly than using a while loop.

I It is always possible to write the same code without recursion,but possibly using extra data structures: stack

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 72

Page 73: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Same structure used for binary trees and doubly-linked lists

struct twoptrs {

struct twoptrs *one, *two;

};

••

••

••

Traversing or deleting is very different for trees or doubly linkedlists.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 73

Page 74: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Tree building example

struct twoptrs {

struct twoptrs *one, *two;

};

...

struct twoptrs *p1 = malloc(sizeof(struct twoptrs));

struct twoptrs *p2 = malloc(sizeof(struct twoptrs));

struct twoptrs *p3 = malloc(sizeof(struct twoptrs));

p3->one = p1;

p3->two = p2;

••

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 74

Page 75: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Doubly-linked list building example

struct twoptrs {

struct twoptrs *one, *two;

};

...

struct twoptrs *p1 = malloc(sizeof(struct twoptrs));

struct twoptrs *p2 = malloc(sizeof(struct twoptrs));

p1->one = p2;

p2->two = p1;

••

••

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 75

Page 76: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

ExerciseDraw the memory produced by the following code.

struct twoptrs {

struct twoptrs *ptrone, *ptrtwo;

}

struct twoptrs *p1, *p2, *p3;

p1 = malloc(sizeof(struct twoptr));

p2 = malloc(sizeof(struct twoptr));

p3 = malloc(sizeof(struct twoptr));

p1->ptrone = NULL;

p1->ptrtwo = NULL;

p2->ptrone = NULL;

p2->ptrtwo = NULL;

p3->ptrone = p1;

p3->ptrtwo = p2;

p1->ptrone = p3;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 76

Page 77: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Draw the memory produced by the following code.

struct twoptrs {

struct twoptrs *ptrone, *ptrtwo;

}

struct twoptrs *p1, *p2, *p3;

p1 = malloc(sizeof(struct twoptr));

p2 = malloc(sizeof(struct twoptr));

p3 = malloc(sizeof(struct twoptr));

p1->ptrone = NULL;

p1->ptrtwo = p2;

p2->ptrone = p1;

p2->ptrtwo = p3;

p3->ptrone = p2;

p3->ptrtwo = NULL;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 77

Page 78: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example: doubly linked list traversal

struct doublylinked {

int data;

struct doublylinked *next;

struct doublylinked *prev;

};

void printdl(struct doublylinked *p)

{

while(p) {

printf("%10d", p->data);

p = p->next;

}

printf("\n");

}

Exercise: write the above using recursion rather than while.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 78

Page 79: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example: doubly linked list item deletion

struct doublylinked {

int data;

struct doublylinked *next;

struct doublylinked *prev;

};

void removedl(struct doublylinked *p)

{

if(!p) return;

if(p->prev)

p->prev->next = p->next;

if(p->next)

p->next->prev = p->prev;

free(p);

}

Exercise: why does this work? Explain by drawing the memory.Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 79

Page 80: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example: some complicated structs in Doug Lea’s malloc

struct malloc_chunk {

size_t prev_foot; /* Size of previous chunk (if free). */

size_t head; /* Size and inuse bits. */

struct malloc_chunk* fd; /* double links -- used only if free. */

struct malloc_chunk* bk;

};

struct malloc_tree_chunk {

/* The first four fields must be compatible with malloc_chunk */

size_t prev_foot;

size_t head;

struct malloc_tree_chunk* fd;

struct malloc_tree_chunk* bk;

struct malloc_tree_chunk* child[2];

struct malloc_tree_chunk* parent;

bindex_t index;

};

From ftp://g.oswego.edu/pub/misc/malloc.cHayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 80

Page 81: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Each node is part of both a tree and a doubly-linked list

struct malloc_tree_chunk {

struct malloc_tree_chunk* fd;

struct malloc_tree_chunk* bk;

struct malloc_tree_chunk* child[2];

struct malloc_tree_chunk* parent;

};

••

••

••

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 81

Page 82: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Addresses of structure members

The address operator can be applied to structure membersStructure members have an L-value = location in memory

2s.x

6s.y &(s.y)

&(s.x)

&s

Pointing into the middle of a struct is meaningful (though not verycommon)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 82

Page 83: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structures containing structures vs pointers to them

struct scont {

A a;

B b;

};

scont

struct spoint {

A *ap;

B *bp;

};

•spoint

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 83

Page 84: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Structures inside structures example

What is the difference between B1 and B2?Draw the memory layout.Compare sizeof(struct B1) and sizeof(struct B2).

struct A {

long x[80];

};

struct B1 {

struct A a;

};

struct B2 {

struct A *p;

};

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 84

Page 85: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Quiz

Consider

struct s {

int x;

int y;

};

struct s a;

True of false?

&a == &(a.x)

True of false?

&a == &(a.y)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 85

Page 86: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Is it possible for a pointer to point to itself, like this:

•p

If yes, write the code.There may be more or less clean ways to do it.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 86

Page 87: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

ANY C PROGRAM WITHMEMORY ERRORS IS WRONG

Page 88: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

typedef

typedef

struct s {

...

} t1;

typedef struct s t2;

t1 *p;

We won’t use typedef in the moduleLinus Torvalds does not like typedef either, see Linux code.In C++, there is better syntax for type definitions: using

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 88

Page 89: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

In C, no function inside structs

struct S {

int x, y;

};

void setx(struct C *p, int n)

{

p->x = n;

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 89

Page 90: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Object oriented in C++, like Java

struct S {

int x, y;

void setx(int n) { x = n; }

};

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 90

Page 91: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Extending structs

struct SinglyLinked {

struct SinglyLinked next;

int data;

};

struct DoublyLinked {

struct DoublyLinked *n;

int data;

struct DoublyLinked *p;

};

what about:

struct DoublyLinked {

int data;

struct DoublyLinked *next;

struct DoublyLinked *prev;

};

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 91

Page 92: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer arithmetic and arrays

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 92

Page 93: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

while(*p++ = *q++);

Page 94: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Strings in C

I In C a string is an array of char terminated by a zero byte

I Zero byte \0 is not the same as the character for “0” (whichis 48 in ASCII).

I The size of the array is not stored (unlike Java).

I You need to keep track of array bounds yourself

I When an array is passed to a function, a pointer to the startof the array is passed, not the contents of the array

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 94

Page 95: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer arithmetic and arrays

I In C, you can add a pointer and an integer

I You cannot add two pointers

I Array access is via pointer arithmetic

I Pointer arithmetic is typed

I p + 1 does not mean p plus one byte

I in p + n, n is scaled up by the size of the type of what ppoints to

I array indexinga[i]

is shorthand for*(a + i)

I Implemented via indexed addressing

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 95

Page 96: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer arithmetic

↑ higher addresses

p+n

...

p + 2

p + 1

p

Each of the cells is sizeof(T) wide if p is of type T

Pointer arithmetic is automagically scaled by the type system

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 96

Page 97: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Prefix and postfix operator precedence

In C, postfix operators bind more tightly than prefix ones.

*p++

is parsed like

*(p++)

Similarly

*f()

is parsed like

*(f())

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 97

Page 98: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

p++ vs (*p)++

p++ increments the pointer p:

...2010 p

...20 p

10

*p++ gives the value of *p before incrementing p, in this case 10.

(*p)++ increments the value pointed to by p:

...2010 p

...2011 p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 98

Page 99: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

p++ vs (*p)++

p++ increments the pointer p:

...2010 p

...20 p

10

*p++ gives the value of *p before incrementing p, in this case 10.

(*p)++ increments the value pointed to by p:

...2010 p

...2011 p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 99

Page 100: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

p++ vs (*p)++

p++ increments the pointer p:

...2010 p

...20 p

10

*p++ gives the value of *p before incrementing p, in this case 10.

(*p)++ increments the value pointed to by p:

...2010 p

...2011 p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 100

Page 101: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

p++ vs (*p)++

p++ increments the pointer p:

...2010 p

...20 p

10

*p++ gives the value of *p before incrementing p, in this case 10.

(*p)++ increments the value pointed to by p:

...2010 p

...2011 p

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 101

Page 102: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

What does this do:

int a[10], *p;

p = a + 2;

p++;

(*p)--;

--*p;

*--p;

*p = *p * *p;

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 102

Page 103: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy idiom from Kernighan and Ritchie

while(*p++ = *q++);

This is typical C code, *p++ etcKernighan and Ritchie: an idiom that should be masteredUnbounded copy is the cause for many, very severe securityvulnerabilities: buffer overflow

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 103

Page 104: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy example

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char from[] = "abc";

char to[4];

mystrcpy(to, from);

\0cba p q

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 104

Page 105: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy example

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char from[] = "abc";

char to[4];

mystrcpy(to, from);

\0cb pa

qa

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 105

Page 106: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy example

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char from[] = "abc";

char to[4];

mystrcpy(to, from);

\0c p

ba

q

ba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 106

Page 107: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy example

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char from[] = "abc";

char to[4];

mystrcpy(to, from);

\0 pcba

qcba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 107

Page 108: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy example

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char from[] = "abc";

char to[4];

mystrcpy(to, from);

p

\0cba

q

\0cba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 108

Page 109: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy overflow

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char a[] = "abc";

char b[2];

mystrcpy(b, a);

\0cba p

zyx

q

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 109

Page 110: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy overflow

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char a[] = "abc";

char b[2];

mystrcpy(b, a);

\0cb pa

zyx

qa

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 110

Page 111: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy overflow

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char a[] = "abc";

char b[2];

mystrcpy(b, a);

\0c p

ba

zyx q

ba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 111

Page 112: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy overflow

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char a[] = "abc";

char b[2];

mystrcpy(b, a);

\0 pcba

zy qcba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 112

Page 113: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

String copy overflow

void mystrcpy(char *q, char *p)

{

while(*q++ = *p++);

}

...

char a[] = "abc";

char b[2];

mystrcpy(b, a);

p

\0cba

z q

\0cba

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 113

Page 114: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Buffer overflow on the call stack

int vulnerable_function()

{

int winner = 0; // suppose this is security-critical

char name[8]; // this is the buffer to be overflown

printf("Please enter your name:\n");

fgets(name, 200, stdin); // too much input

...

}

Input blahblahbl overflows the string variable on the stack:

return address

bl\0 winner

blahblah name

Note: the call stack grows towards lower machine addresses.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 114

Page 115: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Buffer overflows are scary

Page 116: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Buffer overflow prevention and mitigation

I All array accesses in C are potentially dangerous

I Strings in C are arrays and can overflow

I “All input is evil”

I Check bounds for arrays

I Use functions with bounds such as strncpy, fgets

I Watch out for off-by-one errors in bounds

I C compilers do some buffer overflow mitigation (stackcanaries)

I For more, see Seacord, “Secure Programming in C and C++”

I For advanced attacks, you need to understand how C iscompiled (call stack, return address, etc)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 116

Page 117: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Array access in C vs JavaJava does automatic bounds check, C does not.In Java, a[i] either

1. refers to the i-th element of array a

2. throws an out-of-bounds exception if i is too big

In C, a[i] either

1. refers to the i-th element of array a

2. causes undefined behaviour if i is too big

Example:

int a[5];

a[999999999] = 666;

// segfault likely, but anything might happen

But: not doing bounds checks is fasterSuppose you want to multiply two 100000 × 100000 matrices:do you really want the compiler to do a bounds check for eacharray access?

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 117

Page 118: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

ALL INPUT IS EVIL

Always do bounds check on untrusted string inpute.g. coming over the networkotherwise you get pwned with a buffer overflow

Page 119: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Arguments to main = array and count

main takes two arguments: an array of strings and the number ofstrings. The command line arguments are passed this way.

main(int argc, char *argv[]) { ... }

main(int argc, char **argv) { ... }

If we do not need the arguments, we can also write in C (but notC++)

main() { ... }

Exercise: write a main function that prints out its command linearguments using

printf("%s\n", argv[i]);

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 119

Page 120: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A pitfall for Java minions

What does this print, and why?

int n = 6;

printf("The value of n is " + n);

It prints

lue of n is

But why?Not overloading of + for string concatenation as in JavaPointer arithmetic:Beginning of string + 6hence start printing somewhere in the middle of the string

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 120

Page 121: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A pitfall for Java minions

What does this print, and why?

int n = 6;

printf("The value of n is " + n);

It prints

lue of n is

But why?

Not overloading of + for string concatenation as in JavaPointer arithmetic:Beginning of string + 6hence start printing somewhere in the middle of the string

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 121

Page 122: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A pitfall for Java minions

What does this print, and why?

int n = 6;

printf("The value of n is " + n);

It prints

lue of n is

But why?Not overloading of + for string concatenation as in Java

Pointer arithmetic:Beginning of string + 6hence start printing somewhere in the middle of the string

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 122

Page 123: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A pitfall for Java minions

What does this print, and why?

int n = 6;

printf("The value of n is " + n);

It prints

lue of n is

But why?Not overloading of + for string concatenation as in JavaPointer arithmetic:Beginning of string + 6hence start printing somewhere in the middle of the string

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 123

Page 124: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Stack data structure = array + stack pointer

push(10);

push(20);

push(30);

Stack drawn as growing upward:

stack + stacksize - 1

...

stackptr

30 stack + 2

20 stack + 1

10 stack = &stack[0]

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 124

Page 125: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Push and pop using pointer arithmetic

int stack[100];

int *sp = stack;

void push(int n)

{

*sp++ = n;

}

int pop()

{

return *--sp;

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 125

Page 126: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Push onto stack with bounds check

int stack[100];

int *sp = stack;

// invariant: sp points to first free element

void push(int n)

{

if (sp < stack + stacksize - 1)

*sp++ = n;

else {

fprintf(stderr, "Stack overflow!\n\n");

exit(1);

}

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 126

Page 127: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pop from stack with bounds check

int stack[100];

int *sp = stack;

// invariant: sp points to first free element

int pop()

{

if (sp > stack)

return *--sp;

else {

fprintf(stderr, "Stack underflow!\n\n");

exit(1);

}

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 127

Page 128: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example: using a stack to evaluate arithmetic expressions

while(1) {

fgets(input, inputbufsize, stdin);

switch(input[0])

{

case ’0’: case ’1’: case ’2’: case ’3’: case ’4’:

case ’5’: case ’6’: case ’7’: case ’8’: case ’9’:

push(atoi(input));

break;

case ’+’:

push(pop() + pop());

break;

case ’-’:

push(pop() - pop());

break;

default:

printf("Goodbye.\n\n");

return 0;

}

http://www.cs.bham.ac.uk/~hxt/2015/c-plus-plus/StackEval.cHayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 128

Page 129: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Rewrite the stack operations without pointer arithmetic, usingarray indexing instead.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 129

Page 130: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Void pointers as a universal pointer type

I void pointers are a feature of the C type system

I void pointers are a bit of a hack. C++ templates are muchcleaner and more powerful, but not available in C.

I a void pointer should never be dereferenced

I a void pointer can be cast to and from any pointer type

I this has nothing to so with what the pointer points to at runtime.

I in C (but not C++), casts from void pointer may be leftimplicit.

I malloc returns a void pointer

I free takes a void pointer as an argument

I nice C code contains few casts except the implicit ones inmalloc and free

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 130

Page 131: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

A note on void functions vs pointers

I void returning functions void f()

I void pointers void *p

I In functional languages, a void return type is like a unit typewhereas a void pointer is (a little bit) like a polymorphicpointer

I In C++, we do not need void pointer polymorphism, as wehave templates for polymorphism

I In C++, the new operation is typed, so there is no need for avoid pointer as in malloc

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 131

Page 132: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Void pointer example

void *vp; // vp is declared as void pointer

int *ip; // ip is declared as an int pointer

vp = malloc(sizeof(int)); // vp now points into memory

ip = vp; // implicit cast from void pointer

ip = (int*)vp; // explicit cast from void pointer

free(ip); // this does NOT make ip a void pointer

ip = NULL; // neither does this

*vp = 42; // type error, void not int

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 132

Page 133: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointers and casting

Pointer casting does not change what is pointed at.Compare and contrast: cast from int to float.

int x;

float f;

x = 10;

f = (float)x; // f is 10.0

int x;

float *fp;

x = 10;

fp = (float*)&x; // *fp is nonsense, not (float)x

Pointer casting does not perform any dynamic checks.Compare and contrast: casting between objects in Java.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 133

Page 134: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Casting pointers does not change what is pointed at

int x = 5;

int *p1;

float *p2;

p1 = &x;

p2 = (float*)p1;

bitsx

p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 134

Page 135: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Casting pointers does not change what is pointed at

int x = 5;

int *p1;

float *p2;

p1 = &x;

p2 = (float*)p1;

bitsx

•p1 p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 135

Page 136: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Casting pointers does not change what is pointed at

int x = 5;

int *p1;

float *p2;

p1 = &x;

p2 = (float*)p1;

bitsx

•p1 •p2

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 136

Page 137: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer cast example

#include <stdio.h>

int main()

{

int n = 123;

float z = (float)n;

int *p = &n;

float *q= (float *)p;

printf(" n = %d\n z = %e\n*p = %d\n*q = %e\n",

n, z, *p, *q);

}

n = 123

z = 1.230000e+02

*p = 123

*q = 1.723597e-43

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 137

Page 138: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Pointer cast example

#include <stdio.h>

int main()

{

int n = 123;

float z = (float)n;

int *p = &n;

float *q= (float *)p;

printf(" n = %d\n z = %e\n*p = %d\n*q = %e\n",

n, z, *p, *q);

}

n = 123

z = 1.230000e+02

*p = 123

*q = 1.723597e-43

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 138

Page 139: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Quiz

T *p;

p + 1 == (T*)((char*)p + 1)

True or not?

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 139

Page 140: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Quiz

What is wrong with this:

int x;

// some more code

free(&x);

Is there a type error?

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 140

Page 141: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Function pointers are cool.(A student in 2016)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 141

Page 142: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

First-class functions pointer in C and C++

I C has pointers to functions

I In C, functions cannot be defined inside other functions

I Functions in C can be passed as parameter very easily: theyare just code pointers.

I If p is a function pointer, then we can call it via (*p)(...)

I we can omit the * when calling a function via a pointerp(...)

I Note: C++11 has lambda expressions and a general functiontype

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 142

Page 143: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Parsing int *f(int)

Inside out from identifier:

f

f(int)

*f(int)

int *f(int)

Function with an int parameter and returning a pointer to an int

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 143

Page 144: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Parsing int (*f)(int)

Inside out from identifier, not left to right

f

*f

(*f)(int)

int (*f)(int)

Pointer to function taking an int parameter and returning an int

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 144

Page 145: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Scary real world example of function pointer type: signal()

void (*signal (int, void (*)(int))) (int);

signal() is a system call that returns the address of a function thattakes an integer argument and has no return valueThe second argument is a function of type

void (*)(int)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 145

Page 146: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

What are these types in English?

struct s *f(int)

struct s (*f)(struct s (*)(int))

int (*)(int, int)

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 146

Page 147: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example of function pointer: fold function

A binary operator is passed as a function pointer argument.

fold n ⊕ [x1, . . . xn] = n ⊕ x1 ⊕ · · · ⊕ xn

int fold(int n, int (*bin)(int, int),

struct Linked *p)

{

while (p) {

n = bin(n, p->data);

p = p->next;

}

return n;

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 147

Page 148: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Example of function pointer and void pointer: sort function

Quicksort from C library. A comparison function is passed as afunction pointer argument.

void qsort (void* base, size_t num, size_t size,

int (*compar)(void*, void*));

Comparison function using void pointers:

int comparefloat (void *p, void *q)

{

if ( *(float*)p < *(float*)q ) return -1;

if ( *(float*)p == *(float*)q ) return 0;

if ( *(float*)p > *(float*)q ) return 1;

}

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 148

Page 149: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Exercise

Exercise: rewrite the fold function with void pointers so that itworks for arbitrary types (like the qsort function) and not onlyintegers.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 149

Page 150: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

C pointers vs Java references

Object references in Java are similar to C pointers, but safer.A Java reference either

1. is equal to null, or

2. refers to something we can access in memory

A C pointer

1. is equal to NULL, or

2. points to something we can access in memory, or

3. points to something we should not access, as it may causeundefined behaviourexample: p after free(p);example: a[i] = 2; if n is out of bounds

The third possibility makes a huge difference between memory-safelanguages like Java (and OCAML) and and unsafe languages like Cand C++.

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 150

Page 151: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

C nondeterminism vs Java determinism

So when you have a bug

I Java gives you exceptions

I C/C++ gives you segmentation faults

What’s the big deal?C may give you a segfault. It does not have to.Undefined behaviour includes silently changing values in anywherein memory.May be different every time you run the code.Have fun debugging . . .Valgrind to the rescue!

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 151

Page 152: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Conclusion of pointers in C part of the module

You have seen the part of C most relevant to systemsprogramming:

1. pointer types and operations X

2. pointer equality X

3. malloc and free X

4. structures and pointers X

5. pointer arithmetic X

6. strings and pointers X

7. function pointers X

Syntax:

* & = == malloc free struct . -> ++ -- (*f)()

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 152

Page 153: Pointers in C - University of Birminghamhxt/2016/c-plus-plus/pointers-diagrams.pdf · In C++, it is called nullptr The null pointer does not point to anything Dereferencing NULL gives

Conclusions on pointers in COnce you understand pointers in C, they make sensePointers are subtle, but the design of C is consistent andminimalistic, even elegant

Hayo Thielecke University of Birmingham http://www.cs.bham.ac.uk/~hxt 153