Title: Pointers
1Pointers
- Intro and Syntax
- Dynamic memory allocation and linked lists
- Pointers and arrays memory allocation and
efficiency
2Dynamic Memory Allocation Using Pointers
3Dynamic memory allocation with new
- Dynamic memory allocation using new statement
new lttypegt - allocates enough memory from heap (a special part
of memory reserved for dynamic allocation - will
discuss later) to store a type value - also returns the address of this memory location
- need to assign this address to a pointer variable
for processing - Example
- double p //a pointer for double type, but
currently points nowhere - p new double // memory is allocated to store
a double value, but - //currently not initialized. p now
points to that location
4Dynamic memory allocation with new
- int intPtr
- intPtr new int
- // new keyword dynamically allocates enough
memory for a // single int, and returns its
address - intPtr 2 // in general, the new keyword
dynamically allocates enough // memory for the
following type and count - intPtr new int4 //what happened to the
previous pointer?
5Pointers with user-defined types/classes
- You can have pointers for any type
- built-in or user-defined types, classes and
structs - E.g. int, double, char, string, robot, dice,
date, - Similarly, you can dynamically allocate memory
for any type - i.e. you can use any type with new
- eg.
- myClass classPtr
- classPtr new myClass // dynamically allocates
enough memory for - // a myClass object, and stores the address
in //classPtr. - // this
automatically invokes the class constructor.
6Pointers with user-defined types/classes
- Example
- Date finalptr new Date(01, 29, 2005)
- a new Date object is created with value January
29, 2005 and finalptr points to it. - You can have a vector/array of pointers
- tvector ltint gt intptrs(10)
- a vector with 10 integer pointers, currently
point nowhere - We will come to this type of use (array of
pointers) later (see ptrdemo2.cpp)
7Pointers with new
- Date today
- Date p_date //preferred naming for pointers -
starts with p - //declaration and initialization
- Date p1 new Date() //p1
- Date p3 new Date(29,2,2003) //p3
- Date p2 p1 //p2
- Date tomorrow p1 1 // tomorrow
- ...
Todays date
29/2/2003
8Pointer to Class Members
- Date today //Assume today is 27/2/2004
- Date p_date //preferred naming - starts with
p - Date p1 new Date() //p1
- Date p2 p1 //p2
- Date tomorrow p1 1 //tomorrow
-
- int month (p1).Month() //month
- int day p1-gtDay() //day
27/2/2004
28/2/2004
2
27
ptr-gt is a shorthand for (ptr). if ptr is a
pointer to a struct or a class
9Basic Pointer Demo self study demo date was
27/2/2003
- include ltiostreamgt
- using namespace std
- include "tvector.h"
- include "date.h"
- include "dice.h"
- int main()
-
- Date today
- Date nextDay new Date(today1)
- Date prevDay new Date(today-1)
-
- cout ltlt "today\t\t tomorrow\t\t yesterday" ltlt
endl - cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl - cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl -
- nextDay prevDay
- cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl - prevDay 2
Address 0x00001110 0x0001af00
10Basic Pointer Demo Outputdemo date (today)
27/2/2003
- Date today
- Date nextDay new Date(today1)
- Date prevDay new Date(today-1)
- cout ltlt "today\t\t tomorrow\t\t yesterday" ltlt
endl Today NextDay PrevDay - cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl 27/2/2003 0x00001110
0x0001af00 - cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl 27/2/2003 28/2/2003
26/2/2003 -
- nextDay prevDay
- cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl 27/2/2003 26/2/2003
26/2/2003 -
- prevDay 2
- cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl 27/2/2003 28/2/2003
28/2/2003 - cout ltlt today ltlt "\t" ltlt nextDay ltlt "\t" ltlt
prevDay ltlt endl 27/2/2003 0x0001af00
0x0001af00 - with the memory allocation shown on the previous
slide.
11Static vs. Dynamic Memory Allocation
- Automatic (ordinary) variables Normal
declaration of variables within a function
(including main) e.g. ints, chars that you
define by int n , char c etc.. - C allocates memory on the stack (a pool of
memory cells, more on this later) when that
function begins, releases the space when the
function completes. - the lifetime of an automatic variable is defined
by its scope (the compound block in which the
variable is defined). After the block finishes,
the variable returns back to the memory -
- Dynamic variables Allocated by the new operator,
on the heap (a storage pool of available memory
cells for dynamic allocation) - - System will return NULL if there is no more
space in heap to be allocated. - - Programmer should use delete to release space
when it is no longer needed. - the lifetime of a dynamic variable is until they
are explicitly deleted -
12Heap/Stack usage overview
- Stack
- The stack is useful for storing context. If a
procedure simply pushes all its local variables
(part of its context) onto the stack when it
enters, and pops them off when its done, its
complete context is nicely cleaned up
afterwards. - When a procedure calls another procedure, the
called procedure can do the same with its
context leaving the calling procedure's data
completely alone. - HEAP
- The heap is basically all the rest of memory the
program has. In that sense, it is often the
largest segment in a program. Programs use the
heap to hold data that must exist after a
function call returns. - The compiler needs to know the size of the
variables allocated on the stack in order to
bring in (and out) the variable space of a
function. - Dynamic variables are allocated on the heap and
memory allocated for them stays, until explicitly
freed. -
13Heap/Stack
- Where are pointer variables stored, stack or
heap? - Pointer variables (themselves), just like the
normal built-in variables and objects (int,
double, string, tvector, etc.) also use up
memory, but not from the heap - they use the run-time stack
14Pointers Delete
- The statement to de-allocate a memory location
and return to the heap is - delete PointerVariable
- the memory location pointed by PointerVariable is
now returned back to the heap - this area now may be reallocated with a new
statement - careful PointerVariable still points to the same
location, but that location is no longer used - may cause confusion, so it may be a good idea to
reset the pointer to NULL (zero) after deleting. - e.g. p NULL
- a NULL pointer means that it points nothing
(terminating condition for linked lists that we
will see in a moment) - See and run ptrdemo4.cpp for details
15Freeing allocated memory with delete
- Date today
- Date p_date //preferred naming - starts with
p - //declaration and initialization
- Date p1 new Date() //p1
- Date p3 new Date(29,2,2003)
- Date p2 p1 //p2
- Date tomorrow p1 1 // tomorrow
- ...
- Delete p1 //We need to delete memory allocated
with new - Delete p3 //Deleting (freeing) previously freed
memory causes a crash
27/2/2003
28/2/2003
16Pointers to variables on the stack
- Can we have a pointer to point a variable that
is not dynamically allocated? - - using the (address of) operator
- - such variables are not allocated from heap!
- that is why their addresses are not close to
dynamically allocated variables (run
ptrdemo3.cpp) - int num
- int ptr
- num5
- ptr num //ptr contains the address of num
- cout ltlt ptr ltlt endl
- What is output?
17Question
- int n
- int p_temp n
- Do we need to delete p_temp?
- No. It points to a stack variable.
- What happens if we delete?
- Most likely a crash or corrupt program,
depending on the compiler.
18Pointers for Implementing Linked Lists
19Linked Lists
- Arrays too much or too little memory may be
allocated - ease of use
- direct access
- inserting an element into a sorted array may
require shifting - all the elements
- Tvectors may be resized but inefficient
- still some space wasted
- inserting an element into a sorted array may
require shifting - all the elements
-
20Linked Lists
- Linked lists dynamic memory allocation
- insertion/deletion is cheap
- more cumbersome to program with
head tail
21Introduction to linked lists definition
- Consider the following struct definition
- struct node //node is a user given name
-
- string word
- int num
- node next // pointer for the next node
-
- node p new node
?
?
p
?
word
next
num
22Introduction to linked lists inserting a node
- node p
- p new node
- p-gtnum 5
- p-gtword "Ali"
- p-gtnext NULL
- Note that you should normally have a
constructor for the struct this is for
illustraion of the pointer usage. -
5
Ali
p
word
next
num
?
23Introduction to linked lists adding a new node
- How can you add another node that is pointed by
p-gtlink? - node p
- p new node
- p-gtnum 5
- p-gtword "Ali"
- p-gtnext NULL
- node q
-
q
5
Ali
?
p
word
link
num
?
24Introduction to linked lists
- node p
- p new node
- p-gtnum 5
- p-gtword "Ali"
- p-gtnext NULL
- node q
- q new node
-
q
5
Ali
?
?
p
word
link
num
word
link
num
?
25Introduction to linked lists
- node p, q
- p new node
- p-gtnum 5
- p-gtword "Ali"
- p-gtnext NULL
- q new node
- q-gtnum8
- q-gtword "Veli"
q
5
Ali
8
Veli
?
?
p
word
next
num
word
next
num
?
26Introduction to linked lists
- node p, q
- p new node
- p-gtnum 5
- p-gtword "Ali"
- p-gtnext NULL
- q new node
- q-gtnum8
- q-gtword "Veli"
- p-gtnext q
- q-gtnext NULL
q
5
Ali
8
Veli
?
p
word
link
num
word
link
num
27Linked Lists Typical Functions
- Printing an existing list pointed by head
- struct node
- int info
- node next
-
- node head, ptr
- //list is filled here...
- //head points to first node
head tail
ptr head while (ptr ! NULL) cout ltlt ptr
-gtinfo ltlt endl ptr ptr-gtnext
28Linked Lists building
node
node
node
//From strlink.cpp in Tapestry code struct node
int info node next string
storage 1, 2, 3, 4 node head
0 node temp NULL for (int k0 k lt 4
k) temp new node() temp-gtinfo
storagek temp-gtnext first head temp
head tail
head
...
temp
29Linked Lists building
node
node
node
//From strlink.cpp in Tapestry code struct node
int info node next node (const
string s, node link) info(s), next
(link) string storage 1, 2, 3,
4 node head, tail for (int k0 k lt 4
k) temp new node (storagek, head) temp
new node() temp-gtinfo storagek temp-gtnext
head head temp
head tail
You SHOULD use a constructor to insert data more
compactly and in a less error-prone fashion
like this.
head
...
temp
30Reminder structs as data aggregates see
Tapestry Chp. 7 pp. 330-
- If you need multiple arrays with tied elements
(e.g. gradesMAXCLASS_SIZE, namesMAXCLASS_SIZE.
..) or in general, any tied data, you should
consider using a data structure called struct - struct point
-
- double x_coord
- double y_coord
-
- point p1, p2
- p1.x_ccord 10.0 //access members using the
dot notation - p1.y_ccord 0.0
- ...
- Very similar to classes - but no member
functions. You should use structs rather than
classes only when you want to use them as data
aggregates, without any member function (you
should have a constructor though, see the next
slide).
31Reminder Structs with constructors
- If you define a constructor (or two)
- struct point
-
- double x
- double y
-
- //default constructor
- pointpoint()
-
- x 0
- y 0
-
- //constructor
- pointpoint(int x_coord, int y_coord)
- x (x_coord),
- y (y_coord)
- //nothing more to initialize
-
Instead of point curve100 curve0.x
0 curve0.y 0 curve1.x 7 curve1.y
12 ... You can use
point curve100 curve0 point
(0,0) curve1 point (7, 12) //a temporary
point object
32Linked Lists deleting...
1
2
3
//recursive Void DeleteList ( node head) if
(head ! 0) DeleteList(head-gtnext)
delete head Unrolling the execution steps
would look like this with the above
list DeleteList(ptr to node2)
DeleteList(ptr to node 3)
DeleteList(null) //does nothing since
Delete ptr-to-node3 Delete
ptr-to-node2 Delete ptr-to-node1 Notice that
statements which are aligned occur in the same
call to DeleteList (there are several of them)
and execution order is top to bottom.
NULL
head tail
33Linked Lists deleting...
node
node
node
//recursive Void DeleteList ( node head) if
(head ! 0) DeleteList(head-gtnext)
delete head //iterative Void DeleteList (
node head) void AddInOrder (node head)
Node temp while (head ! 0) ...
//hw. question temp head-gtnext
delete head head temp
head tail
34Linklist no header node
- //orderedlist.cpp
- Node AddInOrder(Node list, int newkey)
- // pre list is sorted
- // post add newkey to list, keep list sorted,
return new list with newkey in it -
- Node first list // hang onto first
node -
- // if new node should be first, handle this
case and return - if (list 0 newkey lt listgtinfo)
- return new Node(newkey,first)
-
- while (list-gtnext ! 0 list-gtnext-gtinfo lt
newkey) - list list-gtnext
- // postcondition list-gtinfo lt newkey lt
list-gtnext-gtinfo -
- list-gtnext new Node(newkey,list-gtnext)
- return first
-
35Linklist no header node - Alternative
- //orderedlist.cpp
- Node AddInOrder(Node list, int newkey)
- // pre list is sorted
- // post add newkey to list, keep list sorted,
return new list with newkey in it -
- Node first list // hang onto first
node - Node prev
- // if new node should be first, handle this
case and return - if (list 0 newkey lt listgtinfo)
- return new Node(newkey,first)
-
- while (list ! 0 list-gtinfo lt newkey)
- prevlist //hold onto previous
node so we do not pass too far - list list-gtnext
- // postcondition prev-gtinfo lt newkey lt
list-gtinfo -
- list-gtnext new Node(newkey,list-gtnext)
36Recursive version
- Note these are not class member functions, but
free functions. In hw1, you will be asked to
write a linked list class. - Node AddInOrder ( Node list, int newkey)
- pre list is sorted
- post s is added into its proper place in the
list -
- //new node should come first
- if (list 0 newkey lt list-gtinfo)
- return new Node(newkey,list)
- list-gtnext AddInOrder (list-gtnext, newkey)
- return list
-
- Notice that the first two cases (base cases) are
the same as in the iterative version given in the
previous slide.
newkey
list
37Be Careful
- Remember to guard every pointer dereference so as
not to access the contents of a NULL pointer.
e.g. - while (p ! NULL p-gtinfo lt key)
- ...
- as opposed to
- while (p-gtinfo lt key)
- ...
- which would crash your program when you hit a
NULL ptr.
38Dummy Header Node
- It is often best to use a dummy header node so
that each node has a predecessor (when we stop in
InsertOrder, prev actually will point to the
previous node) - Node list new Node(Dummy, NULL) or
-
- Node list new Node(-1, NULL)
- ...
- Also without the dummy node, you may need to pass
the list as reference. Whereas with the dummy
node, since the header node will always exist and
remian unchanged, you wont need this.
-1 5
7 NULL
list