03 Pointers LL
03 Pointers LL
This lecture prepared by the instructors at the University of Manitoba in Canada and has been modified by Dr. Ahmad Reza Hadaegh
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 1
0000
Dynamic Allocation
- Main memory can be thought of as a (very) large one-dimensional array of memory locations - Each location holds 1 byte and has its own address - Starts at 0 in increments of 1 - Usually in hexadecimal - 0000 - FFFF represents 64K of memory - 64 * 1024 = 65,536 memory locations
0001
0002 0003 0004 0005
FFFF
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 2
Dynamic Allocation
- When variables are declared they are allocated memory - An integer requires (say) 4 bytes and thus gets 4 consecutive locations in memory - Most machines would store an int in 4 bytes - The address of the integer is the first byte and is effectively stored via the variable name
National University
Page
Dynamic Allocation
- An integer variable X would effectively point to the starting address of the 4 bytes required - X must be dereferenced in order to be used - Dereference means to interpret what exists at a particular memory location - Dereference is implicit here
memory
integer variable X
National University
Page
Dynamic Allocation
- It is possible to explicitly declare a variable that contains the address of other variables - Creating variables that are pointers
National University
Page
Dynamic Allocation
typedef int* intptr;
Must be a pointer to a valid C++ type (either built-in or user defined type)
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 6
Dynamic Allocation
Syntax notes: int main ( ) { int* ptr1; int* ptr2; int* ptr3; is the same as ... int main ( ) { int *ptr1, *ptr2, *ptr3;
National University
Page
Dynamic Allocation
- A pointer in C++ must point to storage of a particular type ptr1 is a pointer to an integer - ptr1 is a 4 byte variable that is able to point to a 4 byte variable - The value of ptr1 is not initialized and is at this point garbage
National University
Page
Dynamic Allocation
- To allocate storage for ptr1 to point to: typedef int* intptr;
Dynamic Allocation
- Unlike normal variables, pointers must be explicitly dereferenced
Store 200 in the 4 bytes pointed to by ptr1
*ptr1 = 200;
National University
Page 10
Dynamic Allocation
- Other manipulation may take place
i = *ptr1;
National University
Page 11
Dynamic Allocation
Other manipulation may not sensibly take place
i = ptr1;
Dynamic Allocation
- What happens here? typedef int* intptr; void main () { intptr ptr1; int i; for (i=1;i<=1000;i++) { ptr1 = new int; *ptr1 = 1234; } } ptr1 only exists once -as such, each new points ptr1 to newly allocated 2 byte area The first 999 storage areas are reserved by the OS, but no longer accessible Memory leak!
Dynamic Allocation
- Storage that is allocated via new should be freed via delete during the execution of a program typedef int* intptr;
void main () { intptr ptr1; int i; for (i=1;i<=1000;i++) { ptr1 = new int; *ptr1 = 1234; delete ptr1; } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Page 14
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 15
? P ? Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 16
? P ? Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 17
1 P ? Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 18
1 P ? Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 19
1 P 2 Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 20
1 P 2 Q Output: 1 2
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 21
5 P 2 Q
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 22
5 P 2 Q Output: 5 2
Dynamic Allocation
typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 23
Memory leak!
5 P 2 Q
Dynamic Allocation
typedef int* intptr; Memory leak! void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << << *Q << endl; *P = *Q + 3; cout << *P << << *Q << endl; P = Q; cout << *P << << *Q << endl;
A.R. Hadaegh Dr. Ahmad R. Hadaegh
5 P 2 Q Output: 2 2
National University Page 24
Dynamic Allocation
Memory leak!
*P = 7; cout << *P << << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; }
5 P 7 Q
National University Page 25
Dynamic Allocation
Memory leak! *P = 7; cout << *P << << *Q <<endl P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q Output: 7 7
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 26
Dynamic Allocation
Memory leak!
*P = 7; cout << *P << << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } ?
5 P 7 Q
National University Page 27
Dynamic Allocation
Memory leak!
*P = 7; cout << *P << << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; }
National University
? P
7 Q
Page 28
Dynamic Allocation
Memory leak! *P = 7; cout << *P << << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } P 7 Q
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Page 29
Dynamic Allocation
Memory leaks! *P = 7; cout << *P << << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 30
Dynamic Allocation
NULL - Is a built-in constant that sets a pointer variable to something that can not be dereferenced - Also makes it clear that a pointer variable is in fact not pointing to anything - A garbage pointer may be non NULL and thus look like its pointing to something if (some_pointer = = NULL) cout << pointer points to nothing << endl;
National University
Page 31
Dynamic Allocation
- Probably a good habit to set pointer variables to NULL after deleting them
National University
Page 32
Dynamic Allocation
#include <iostream> using namespace std;
Output?
Page 33
Dynamic Allocation
#include <iostream> using namespace std;
typedef int* intptr; void main () { intptr ptr1; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; cout << *ptr1 << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Output?
Page 34
Dynamic Allocation
- Using NULL does not guarantee that that you protect yourself from doing something silly as in:
National University
Page 35
Dynamic Allocation
#include <iostream> using namespace std; typedef int* intptr;
void main () { intptr ptr1; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; ptr1 = new int; cout << *ptr1 << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Output?
Page 36
Dynamic Allocation
#include <iostream> using namespace std; typedef int* intptr; void main () { intptr ptr1, ptr2; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; ptr2 = new int; ptr1 = new int; cout << *ptr1 << endl; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Output?
Page 37
Dynamic Allocation
- When dealing with pointers, you are responsible for ensuring they do not dangle Note: - Dynamic allocation is one of the most important topic of this course. So you need understand it very well.
National University
Page 38
Link Lists
National University
Page 39
National University
Page 40
Linked Lists
Pointer to next node
top
Data
27
-38
36
node
National University
Page 41
Linked List
- The simplest linked structure - Sometimes called a linear linked list - The result of having an initial pointer to a node - And dynamically created nodes that point to other nodes
National University
Page 42
Linked Lists
- Big advantage over array in that linked list is dynamically created - Use only as many nodes as required for data - List grows and shrinks accordingly
- Linked lists are made up of a pointer (top in this case) that points to the first of a collection of homogeneous nodes - Unlike the nodes, top contains no data top is not dynamically created while the rest of the linked structure is
National University
Page 43
Linked Lists
- All that exists at this time is an uninitialized pointer to a node - No nodes have been allocated yet - To make it clear the linked list is empty
top = NULL;
NULL is a special C++ constant
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 45
National University
Page 46
Dereferencing
- Given that a node exists and given that a pointer exists that contains the nodes address, the contents of the node may be modified - Again, using a pointer to reference storage is called dereferencing
Note the arrow notation that allows access to a field within a node
National University
Page 47
Dereferencing
- Now have: Remember that top is a declared variable -- a pointer to a node
top
123
This node is not a variable -it is dynamically allocated via the new statement
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 48
New (again)
top = new node; // again! top now points to a new node
top
top
123
123 Old node still exists, but can no longer be accessed -memory leak!
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 49
Delete
- Linked lists are dynamic which means they can grow and shrink appropriately
- Grow with new - Shrink with delete
National University
Page 50
Delete
- delete top; top now contains garbage
top
top
123
123
Insert
- Inserting many nodes: - Important to be able to insert more than a single node into a linked list
National University
Page 52
Insert
- Assume an existing linked list structure and definition
nodeptr newnode;
top
27
-38
36
National University
Page 53
Insert
newnode = new node; newnode -> number = 123; newnode -> next = top; top = newnode; newnode This code assumes you always want to place a newly allocated node at the front of the list
top
123
27
-38
36
National University
Page 54
Searching
- Many operations upon a linked structures involve searching.
bool search (nodeptr top, int key) { nodeptr curr=top; bool found=false; while ((curr != NULL) && (!found)) if (curr -> number == key) found = true; else curr = curr -> next; return (found); }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 55
More on Inserting
- Have seen inserting a node to the front of a linked list - Possible that this might not be satisfactory - If a list is to be maintained in sorted order (for example), an insert might have to be done in the middle or the the end of the list
National University
Page 56
More on Insert
void insert (nodeptr& top, int item) { nodeptr curr=top, prev=NULL, newnode; bool found=false; newnode = new node; newnode -> number = item; while ((curr != NULL) and (!found)) if (item > curr -> number) { prev = curr; curr = curr -> next; } else found = true; newnode -> next = curr; if (prev == NULL) top = newnode; else prev -> next = newnode; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Insert
Page 57
Deleting
- Removing items from a linked list will normally require a search and knowledge of different cases of delete (much like insert) - Deleting the first node of a linked list requires the manipulation of the top pointer - Deleting a node in the middle of a linked list requires the manipulation of pointers within allocated nodes -- top pointer will remain unchanged - Deleting at the end of a linked list requires the same operations as delete in the middle
National University
Page 58
Deleting
void remove (nodeptr& top, int key) { nodeptr curr, temp; // Code assumes key will be found if (key == top -> number) { temp = top; top = top -> next; } else { curr = top; while (curr -> next -> number != key) curr = curr -> next; temp = curr -> next; curr -> next = curr -> next -> next; } delete temp; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Double dereference
Page 59
Deleting
- For every node that is allocated via new, there should be a node given back to the OS via delete
- This implies that a function should probably exist to destroy an existing linked list
void destroy (nodeptr& top) { nodeptr curr=top, temp; while (curr != NULL) { temp = curr; curr = curr -> next; delete temp; } top = NULL; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh
If you declare and create a linked list within a function without destroying it, you will have a memory leak when you leave the function ends
National University
Page 60
Copying
- Functions can work with more than one linked list at a time - Here is a function that copies one linked list to another:
void copy (nodeptr atop, nodeptr& btop) { nodeptr acurr, bcurr; destroy (btop); // deleted previous nodes in the list if there is any if (atop != NULL) { btop = new node; btop -> number = atop -> number; acurr = atop; bcurr = btop; while (acurr -> next != NULL) { bcurr -> next = new node; acurr = acurr -> next; bcurr = bcurr -> next; bcurr -> number = acurr -> number; } bcurr -> next = NULL; } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 61
Linked lists
- Linked lists are general purpose structures that can be manipulated to solve a diverse set of problems
National University
Page 62