You are on page 1of 52

Pointers II

Aubrey Gress CS 106B July 11, 2011

Review: Pointers
Pointers store memory addresses
Stack Heap

int *heap int y int x int *px

902204 21 7 1000

35

Review: Pointer Operators


int *px 1000 7

Declaring a variable to be variableType* makes it a pointer.


int x = 7; int *px = &x;

int *px int x

1000 7

& returns the address of the variable


int x = 7; int *px = &x; *px = 12;

int *px int x

1000
12

* dereferences a pointer

Review: Pointer Operators


Vector<int> vec; Vector<int> *p = &vec; p->Add(7); Vector<int> vec Vector<int> *p 1000

vec->Add(7) is equivalent to (*vec).Add(7)

Review: new
Stack
int *px 1000
35

Heap

int *px; px = new int; *px = 35;

new can be used to allocate memory on the heap

Review: Pointers and References


References are basically just pointers that automatically dereference themselves
int x = 7; foo(&x); //Prints 7 foo(x); //Prints 8 cout << x; //Prints 9

void foo(int *x) { cout << *x << endl; (*x)++; }; void foo(int &x) { cout << x << endl; x++; }

Sizes of datatypes
Every datatype has a size in bytes
char: 1 byte int: 4 bytes double: 8 bytes Vector/Grid/Queue/Map/Stack: many bytes (depends on number of elements) pointer: 4 or 8 bytes (depending on your operating system)

Remember how weve been telling you since week 1 to pass large containers by reference?
1) Saves the cost of copying a large container 2) Since references are just pointers, passing a reference only takes 4 or 8 bytes

32 bit vs 64 bit Pointers


On modern machines pointers are generally either 4 bytes or 8 bytes.
8 bits in a byte, so either 32 bit or 64 bit.

Why do they differ in size?

0 1 2 3 232 - 3 232 - 2 232 - 1

Remember that pointers store memory addresses A 32 bit pointer can store 232 different memory address A 64 bit pointer can store 264 different memory address Pointer size determines how much memory (RAM) your computer can hold

32 bit vs 64 bit Pointers


Maximum Memory of different operating systems
Windows 32 bit: 3 Gigabytes
(Less than 2^32 bytes due to operating system quirks)

Windows 64 bit: 192 Gigabytes


(Less than 2^64 bytes due to operating system quirks)

NULL
Remember that C++ doesnt initialize primitives for you
int x; cout << x << endl;

int x

??????

If a pointer isnt initialized to a value, then the address it points to will be random NULL is a value used to communicate that a pointer doesnt point to anything
Stack
int *px NULL

Heap

int *px = NULL;

NULL
What happens when you run the following code?
int *px; *px = 1;

int *px

??????

Program crashes sometimes What about now?


int *px = NULL; int *px *px = 1;

NULL

Program crashes always

Orphaned Memory
Stack
int *px

Heap

35 int *px; px = new int; *px = 35;

Stack
int *px

Heap

35 px = new int;

????

Orphaned Memory
When a program orphans memory we say it leaks memory

Dont be like Firefox circa 2007

delete
Stack
int *px

Heap

35
???? int *px; px = new int; *px = 35; delete px; px = new int;

delete
Stack
int *px

Heap

???? int *px; px = new int; *px = 35; delete px; px = new int;

delete returns the memory to the operating system, so it can be allocated again to future calls to new

delete
Stack
int *px int *px = new int; *px = 35; delete px;

Heap

35

px still points to same address in memory What happens if we do the following:


*px = 21;

Stack
int *px

Heap

21

Writing or reading after delete will work, but its not safe. Hopefully it will crash your program

delete
Stack
int *px

Heap

????

Why writing after delete is unsafe:


int *px = new int; *px = 21; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

21

Why writing after delete is unsafe:


int *px = new int; *px = 21; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

21

Why writing after delete is unsafe:


int *px = new int; *px = 21; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

int *py

21

Why writing after delete is unsafe:


int *px = new int; *px = 21; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

int *py

Why writing after delete is unsafe:


int *px = new int; *px = 21; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

int *py

21

Why writing after delete is unsafe:


int *px = new int; *px = 35; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Stack
int *px

Heap

int *py

21

int *px = new int; *px = 35; delete px; py = new int; *py = 0; *px = 21; if (*py == 21) KillAKitten();

delete
Java: never need to call delete because Garbage Collector frees memory that is not being used. The lack of a Garbage Collector in C++ is one the reasons C++ is so much harder to program in, but it is one of the major reasons C++ is faster than Java

C++ Arrays
Arrays are a fixed size block of elements
int arr[10]; arr[9] arr[2]
arr[1] int arr[] arr[0]

Stack
??? ???
??? ???

Can use [] to access and modify elements Arrays do not do any bounds checking for you
arr[10] = 7; //Will compile, but you shouldnt do this

Cannot call methods on arrays, and arrays do not know how big they are
arr.size() //ERROR

C++ Arrays
Writing beyond the bounds of an Array it is called a buffer overflow
int bankDeposit = 100; int arr[10]; arr[10] = 0;

Stack
bankDeposit arr[9] 100 ???

arr[2] arr[1] int arr[] arr[0]

??? ??? ???

C++ Arrays
Writing beyond the bounds of an Array it is called a buffer overflow
int bankDeposit = 100; int arr[10]; arr[10] = 0;

Stack
bankDeposit arr[9] 0 ???

arr[2] arr[1] int arr[] arr[0]

??? ??? ???

Many computer security issues are due to buffer overflows

C++ Arrays
Arrays are pointers that point to the first element in the array
Stack
int arr[10]; int *px = NULL; px = arr; px[1] = 5; arr[9] ???

arr[2] arr[1] int arr[] arr[0]

??? ??? ???

C++ Arrays
Arrays are pointers that point to the first element in the array
Stack
int arr[10]; int *px = NULL; px = arr; px[1] = 5; arr[9] ???

arr[2] arr[1] int arr[] arr[0] int *px

??? ??? ??? NULL

C++ Arrays
Arrays are pointers that point to the first element in the array
Stack
int arr[10]; int *px = NULL; px = arr; px[1] = 5; arr[9] ???

arr[2] arr[1] int arr[] arr[0] int *px

??? ??? ???

C++ Arrays
Arrays are pointers that point to the first element in the array
Stack
int arr[10]; int *px = NULL; px = arr; px[1] = 5; arr[9] ???

arr[2] arr[1] int arr[] arr[0] int *px

??? 5 ???

C++ Arrays
The following are valid ways to create an array
const int ARRAY_SIZE = 100; int arr[10]; int otherArr[ARRAY_SIZE];

The following is not legal


int arraySize = GetInteger(); int otherArr[arraySize];

What if youre at a party and want to create an array of arbitrary size?

C++ Arrays
Dynamically allocate an array on the heap
int arrSize = GetInteger(); int *arr = new int[arrSize];

Stack
int *arr
???
arr[0]

Heap
???
arr[1]

???
arr[arrSize-1]

When done with the memory, need to use delete[]


delete[] arr;

Stack
int *arr

Heap
???
arr[0]

???
arr[1]

???
arr[arrSize-1]

Rules for Pointers


If a pointer is not initialized, set it to NULL Before dereferencing a pointer, check if its equal to NULL delete/delete[] memory when youre done with it
Dont Orphan memory

Dont access memory that has been deleted When accessing elements in an Array, check to make sure the index is in bounds

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap
????

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

????

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

????

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

????

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

????

Pointers Just Got Trickier


Last Thursday we said you can have a pointer to any data type. This means that we can have a pointer to a pointer
int **px = new int*; *px = new int; **px = 7;

Stack
int **px

Heap

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
Stack Heap

0 1

???
99

int *[100]

int **p

???
0

???
1

int[2]

???
0

???
1

???
2

int[3]

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int *arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(p); }

Stack
int *p NULL

Heap

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int *arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(p); }

Stack
int *p NULL

Heap

CreateArray() int *arr

////////// NULL

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int *arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(p); }

Stack
int *p NULL ???
0

Heap
???
1

???
99

CreateArray() int *arr

//////////

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int *arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(p); }

Stack
int *p NULL ???
0

Heap
???
1

???
99

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int **arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(&p); }

Stack
int *p NULL

Heap

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int **arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(&p); }

Stack
int *p NULL

Heap

CreateArray() int **arr

//////////

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int **arr) { *arr = new int[100]; }

int main() { int *p = NULL; CreateArray(&p); }

Stack
int *p ???

Heap
???
1

???
99

CreateArray() int **arr

//////////

Pointers Just Got Trickier


We can have pointers to pointers, but why would we ever do that?
void CreateArray(int **arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(&p); }

Stack
int *p ???
0

Heap
???
1

???
99

Pointers Just Got Trickier


Could do the same thing with references
void CreateArray(int *&arr) { arr = new int[100]; }

int main() { int *p = NULL; CreateArray(&p); }

The End

You might also like