Program Memory Allocation - PowerPoint PPT Presentation

1 / 32
About This Presentation
Title:

Program Memory Allocation

Description:

Because a new incarnation of the function is placed upon the run-time stack each ... should halt, and pop the current incarnation of the recursive function off of ... – PowerPoint PPT presentation

Number of Views:27
Avg rating:3.0/5.0
Slides: 33
Provided by: william732
Learn more at: http://www.cs.siue.edu
Category:

less

Transcript and Presenter's Notes

Title: Program Memory Allocation


1
Program Memory Allocation
Each program being executed on a computer is
allocated extra space which it could use for its
stack of function calls, and/or for dynamically
expanding its use of memory for data. The memory
used for data is known as a heap.
2
A Programs Run-Time Stack
Program XYZ
void main() int snap 7 int yap 10
int blap 100 blap snippy(snap)
yippy(yap, blap) zippy(yap) int snippy(int
snoo) int hep yippy(snoo,5) if (hep gt
0) return hep else return
0 void yippy(int yoo, int boo) int i
for (i 1 i lt boo i) yoo i
return void zippy(int zoo) cout ltlt zoo ltlt
endl
3
Recursion
It is sometimes useful to have a function call
itself, making it a recursive function. This
approach often enables the programmer to solve a
problem by repeatedly solving smaller, more
manageable versions of the problem, until the
original problems solution becomes
apparent. Care must be taken when using
recursion, however. Because a new incarnation of
the function is placed upon the run-time stack
each time the function is recursively called,
there is a danger that the stack will
overflow. To prevent this from happening, the
function must contain a termination condition,
which will recognize when the recursion should
halt, and pop the current incarnation of the
recursive function off of the run-time stack.
4
Recursion Example 1 Factorial
//////////////////////////////////////////////////
////////////////////////// // Program file
factorial.cpp
// // This program queries the user for a
non-negative integer and then uses // // a
recursive function to calculate the factorial of
the input value. // ///////////////////////////
/////////////////////////////////////////////////
include ltiostreamgt include ltiomanipgt using
namespace std int factorial(int
n) //////////////////////////////////////////////
////////////// // The main function asks the user
for a value, calls the // // recursive factorial
function, and outputs the result.
// ///////////////////////////////////////////////
///////////// void main() int number,
result cout ltlt "Enter a non-negative integer
for factorial computation " cin gtgt number
while (number lt 0) cout ltlt "I said,
enter a NON-NEGATIVE integer " cin gtgt
number cout ltlt endl result
factorial(number) cout ltlt "FINAL RESULT " ltlt
number ltlt "! " ltlt result ltlt endl ltlt endl
5
Factorial (Continued)
//////////////////////////////////////////////////
/////////////////////////// // Function factorial
recursively calculates the factorial of parameter
n, // // outputting entering and exiting messages
to demonstrate to the user the // // recursive
function calls which make the final calculation
possible. // /////////////////////////////////
//////////////////////////////////////////// int
factorial(int n) static int indent 0
int result cout ltlt setw(indent) ltlt "" ltlt
"ENTERING FACTORIAL ROUTINE WITH N ltlt
n ltlt endl ltlt endl if ((n 1) (n 0))
cout ltlt setw(indent) ltlt "" ltlt "EXITING
FACTORIAL ROUTINE WITH N " ltlt n ltlt
", " ltlt n ltlt "! " ltlt 1 ltlt endl ltlt endl
indent - 4 return 1 else
indent 4 result n factorial(n
- 1) cout ltlt setw(indent) ltlt "" ltlt
"EXITING FACTORIAL ROUTINE WITH N "
ltlt n ltlt ", " ltlt n ltlt "! " ltlt result ltlt endl ltlt
endl indent - 4 return result

6
Factorial (Continued)
7
Tracing Through Factorials Run-Time Stack
8
Recursion Example 2 Exponentiation
//////////////////////////////////////////////////
//////////////////////////// // Program file
exponent.cpp
// // This program queries the user for
a floating-point base and an integer // //
exponent, and then uses a recursive function to
calculate the value of // // the base raised to
the power.
// ///////////////////////////////////////////
/////////////////////////////////// include
ltiostreamgt include ltiomanipgt using namespace
std double exponentiate(double base, int
power) //////////////////////////////////////////
//////////////////// // The main function asks
the user for a value, calls the // // recursive
exponentiate function, and outputs the result.
// ///////////////////////////////////////////////
/////////////// void main() double base,
result int power cout ltlt "Enter a
floating-point base value " cin gtgt base
cout ltlt "Enter an integer exponent " cin gtgt
power cout ltlt endl result
exponentiate(base, power) cout ltlt endl ltlt
"FINAL RESULT " ltlt base ltlt '' ltlt power
ltlt " " ltlt result ltlt endl ltlt endl
9
Exponentiation (Continued)
//////////////////////////////////////////////////
//////////////////////////// // Function
exponentiate recursively calculates the value of
raising // // parameter base to the
parameter power's exponent, outputting entering
// // and exiting messages to demonstrate to the
user the recursive function // // calls which
make the final calculation possible.
// ////////////////////////////////////
////////////////////////////////////////// double
exponentiate(double base, int power) static
int indent 0 double result
cout.setf(iosfixed) cout ltlt setprecision(8)
ltlt setw(indent) ltlt "" ltlt "ENTERING
EXPONENTIATE ROUTINE WITH POWER ltlt power ltlt
endl if (power 0) result 1.0 else
if (power gt 0) indent result
base exponentiate(base, power - 1) else
indent result exponentiate(base,
power 1) / base cout ltlt setw(indent) ltlt
"" ltlt "EXITING EXPONENTIATE ROUTINE WITH POWER
" ltlt power ltlt ", " ltlt base ltlt '' ltlt
power ltlt " " ltlt result ltlt endl indent--
return result
10
Exponentiation (Continued)
11
Recursion Example 3 Logarithm
//////////////////////////////////////////////////
/////////////////////////////// // Program file
logarithm.cpp
// // This program queries the user
for a value and a base, then uses a recursive
// // function to calculate the value of the
logarithm of the value to the base.
// ///////////////////////////////////////////////
////////////////////////////////// include
ltiostreamgt include ltiomanipgt include
ltcmathgt using namespace std void
queryUser(double value, double base) int
myLog(double value, double base) // Main asks
the user for a value, calls recursive log, and
outputs result. // void main() double value,
base char yORn cout.setf(iosfixed)
cout ltlt "Would you like to put a log on the fire?
(Enter Y or N) " cin gtgt yORn while ((yORn
'y') (yORn 'Y'))
queryUser(value, base) cout ltlt
"Approximate log " ltlt myLog(value, base) ltlt
endl ltlt "Real log " ltlt
log(value)/log(base) ltlt endl ltlt endl cout
ltlt "Would you like to put another log on the
fire? (Enter Y or N) " cin gtgt yORn
12
Logarithm (Continued)
// Function queryUser asks the user for positive
values for // // both the floating-point value
and the logarithmic base. // void
queryUser(double value, double base) do
cout ltlt "Enter a positive floating-point
value " cin gtgt value while
(value lt 0.0F) do cout ltlt "Enter a
floating-point base (greater than one) "
cin gtgt base while (base lt 1.0F) //
Function log recursively calculates the integer
value of taking the // // logarithm (to the
parameterized base) of the parameterized value.
// int myLog(double value, double base) int
result if ((value gt 1/base) (value lt
base)) result 0 else if (value lt
1/base) result myLog(valuebase, base) -
1 else result myLog(value/base, base)
1 return result
13
Logarithm (Continued)
14
Recursion Example 4 Combination
15
Combination (Continued)
//////////////////////////////////////////////////
/////////////////// // Program file
combination.cpp
// // This program queries the user for a set
size and a subset size, // // and then
recursively computes the number of different
subsets // // of the appropriate size that
could be selected from the set.
// ///////////////////////////////////////////////
////////////////////// include ltiostreamgt using
namespace std int computeCombo(int setSize, int
subsetSize) // Main asks the user for the set
subset sizes, calls the // // function
producing the combination, and outputs the
result. // void main() int
sizeOfCollection int sizeOfSelection cout
ltlt "How many objects in the master collection?
" cin gtgt sizeOfCollection cout ltlt "How
many objects in a single selection? " cin gtgt
sizeOfSelection cout ltlt endl ltlt endl cout
ltlt "FOR " ltlt sizeOfCollection ltlt " FANCY OBJECTS
COLLECTED" ltlt endl ltlt "AND " ltlt
sizeOfSelection ltlt " LUCKY CHOICES SELECTED," ltlt
endl ltlt "THERE\'S " ltlt computeCombo(sizeOf
Collection, sizeOfSelection) ltlt "
DIFFERENT SUBSETS" ltlt endl ltlt "BUT EACH
HAS " ltlt sizeOfCollection-sizeOfSelection
ltlt " ANGRY UPSETS" ltlt endl ltlt "\'CAUSE
THE REST OF THE SAPS ARE REJECTED!" ltlt endl ltlt
endl
16
Combination (Continued)
//////////////////////////////////////////////////
/////////// // Function computeCombo recursively
calculates the number // // of different
combinations of size subsetSize that can // //
be obtained from a collection of size setSize.
// /////////////////////////////////////////
//////////////////// int computeCombo(int
setSize, int subsetSize) if ((subsetSize 0)
(subsetSize setSize)) return 1 if
(subsetSize gt setSize) return 0 return
(computeCombo(setSize-1, subsetSize-1)
computeCombo(setSize-1, subsetSize))
17
Recursion Example 5 Binary Search
While its a lot easier to write a program that
searches a sorted list by merely looping through
the whole list (i.e., a sequential, or linear,
search), its not exactly an efficient way of
getting the job done. A more efficient approach
is to use a binary search Look at the middle
element of the list. If thats the value you
seek, then youre done. If its not, then its
either larger or smaller than the value you seek.
Since the list is sorted, you can just proceed
with either the first half of the list (if the
middle value was larger) or the second half (if
the middle value was smaller). In either case,
youve cut the size of the problem in half.
Thats recursion!
// Library header file boolean.h ifndef
BOOL_H undef TRUE undef FALSE const int TRUE
1 const int FALSE 0 typedef int
boolean define BOOL_H endif
Lets begin by creating our own boolean type, to
make our code easier to read. Just make sure to
include this homemade header file in the program,
and to add it to the project when you try to
build the executable file.
18
Binary Search (Continued)
//////////////////////////////////////////////////
////////// // Program file binarySearch.cpp
// // This program sets up a
sorted list of integers, and // // then allows
the user to interactively search the // //
list for values by means of a recursive binary
search. // ///////////////////////////////////////
///////////////////// include ltiostreamgt include
ltcstdlibgt include ltctimegt include
"boolean.h" using namespace std const LIST_SIZE
100 const HI_RAND_INT 32767 void
generateList(int list) int randomValue(int
lowerBound, int upperBound) boolean
binSearch(const int list, int firstIndex, int
lastIndex, int soughtValue, int
correctIndex)
19
Binary Search (Continued)
//////////////////////////////////////////////////
///////// // Main sets up the sorted list of
integers, and then // // repeatedly asks the
user for the for values to be // // found (or
not found) via the recursive binary search.
// ///////////////////////////////////////////////
//////////// void main() int
sortedListLIST_SIZE int valueToFind int
location generateList(sortedList) cout
ltlt "RECURSIVE BINARY SEARCH TEST" ltlt endl ltlt
endl cout ltlt "Enter a value to be sought in
the list (use a negative value to quit) "
cin gtgt valueToFind while (valueToFind gt 0)
if (binSearch(sortedList, 0, LIST_SIZE-1,
valueToFind, location)) cout ltlt "Value "
ltlt valueToFind ltlt " was found at
index " ltlt location ltlt endl ltlt endl else
cout ltlt "Value " ltlt valueToFind
ltlt " was not found in the list" ltlt endl ltlt
endl cout ltlt "Enter another value for the
search (use a negative value to quit) "
cin gtgt valueToFind cout ltlt endl ltlt
endl return
20
Binary Search (Continued)
//////////////////////////////////////////////////
//////// // Function generateList fills an
integer array with // // values in such a way
that the array element at index // // i will
contain some value between 10i and 10i9.
// ///////////////////////////////////////////////
/////////// void generateList(int list)
for (int i 0 i lt LIST_SIZE i) listi
i10 randomValue(0,9) return /////////
//////////////////////////////////////////////////
/// // Function randomValue generates a
pseudorandom integer in // // the range between
lowerBound and upperBound (inclusive).
// ///////////////////////////////////////////////
/////////////// int randomValue(int lowerBound,
int upperBound) static boolean firstTimeHere
TRUE long int randomNumberSeed if
(firstTimeHere)
// The first time this function is called,
time(randomNumberSeed) // use the current
system time to seed the srand(randomNumberSe
ed) // random number generator, avoiding
identical firstTimeHere FALSE //
results each time the program is run.
return int((upperBound-lowerBound1)(float(rand()
)/HI_RAND_INT) lowerBound)
21
Binary Search (Continued)
//////////////////////////////////////////////////
//////////////////// // Function binSearch
recursively examines the integer array list
// // (assumed to already be sorted) for
soughtValue. If it finds it, // // it places the
index of its location in the array in parameter
// // correctIndex and terminates. The only
other termination // // condition occurs
when the search is completely unsuccessful.
// ///////////////////////////////////////////////
/////////////////////// boolean binSearch(const
int list, int firstIndex, int lastIndex,
int soughtValue, int correctIndex)
int middleIndex (firstIndex lastIndex) /
2 if (lastIndex lt firstIndex) return
FALSE else if (listmiddleIndex
soughtValue) correctIndex
middleIndex return TRUE else if
(listmiddleIndex lt soughtValue) return
binSearch(list, middleIndex1, lastIndex,
soughtValue, correctIndex) else return
binSearch(list, firstIndex, middleIndex-1,
soughtValue, correctIndex)
22
Binary Search (Continued)
23
Recursion Example 6 Maze Solving
//////////////////////////////////////////////////
///////////////////////////// // This program
uses recursion to traverse a maze in the form of
a character // // matrix, finding the path
through the maze, and marking it with asterisks.
// ///////////////////////////////////////////////
//////////////////////////////// include
ltiostreamgt include ltfstreamgt include
"boolean.h" using namespace std const int
MATRIX_SIDE 21 enum direction north, east,
south, west void getMaze(char
matrixMATRIX_SIDEMATRIX_SIDE, int startRow,
int startCol, int destRow, int
destCol) void solveMaze(char matrixMATRIX_SIDE
MATRIX_SIDE, int startRow, int startCol,
int destRow, int destCol) boolean
proceed(char matrixMATRIX_SIDEMATRIX_SIDE,
direction startDirection, int
startRow, int startCol, int destRow, int
destCol) void printMatrix(char
matrixMATRIX_SIDEMATRIX_SIDE) // Function
main retrieves, solves, outputs the maze. // void
main() char matrixMATRIX_SIDEMATRIX_SIDE
int startRow, startCol int destRow,
destCol getMaze(matrix,startRow, startCol,
destRow,destCol) solveMaze(matrix,startRow,sta
rtCol,destRow,destCol) printMatrix(matrix)
24
Maze Solving (Continued)
//////////////////////////////////////////////////
/////////////////////////////// // Function
getMaze retrieves the maze matrix from a specific
input file, // // assuming that it is size
MATRIX_SIDE x MATRIX_SIDE, and that it is stored
// // as MATRIX_SIDE lines of MATRIX_SIDE
characters. The four function // //
parameters will be assigned the row and column
numbers of the entrance and // // exit to the
maze (assuming that the entrance is either on the
left side or // // the top of the matrix, and
the exit is on the side opposite the entrance).
// ///////////////////////////////////////////////
////////////////////////////////// void
getMaze(char matrixMATRIX_SIDEMATRIX_SIDE,
int startRow, int startCol, int
destRow, int destCol) int i, j
ifstream sourceFile char nextChar
sourceFile.open("C\\TEMP\\maze") for (i 0
i lt MATRIX_SIDE i) for (j 0 j lt
MATRIX_SIDE j)
sourceFile.get(nextChar) while
(nextChar '\n') sourceFile.get(next
Char) matrixij nextChar

25
Maze Solving (Continued)
for (i 1 i lt MATRIX_SIDE-1 i)
if (matrixi0 ' ')
startRow i startCol 0
else if (matrix0i ' ')
startRow 0 startCol i
if (matrixiMATRIX_SIDE-1 ' ')
destRow i destCol
MATRIX_SIDE-1 else if
(matrixMATRIX_SIDE-1i ' ')
destRow MATRIX_SIDE-1 destCol i
return
26
Maze Solving (Continued)
//////////////////////////////////////////////////
//////////////////////////////// // Function
solveMaze kicks off the recursion which will find
(and mark) a path // // through the maze.

// //////////////////////////////////////////////
//////////////////////////////////// void
solveMaze(char matrixMATRIX_SIDEMATRIX_SIDE,
int startRow, int startCol, int
destRow, int destCol) if (startRow 0)
proceed(matrix,east,startRow,startCol,destRow,dest
Col) else proceed(matrix,south,startRow,sta
rtCol,destRow,destCol) ///////////////////////
//////////////////////////////////////////////////
///////// // Function proceed recursively
proceeds through the maze, trying to ascertain
// // the path to the exit. Parameter
startDirection retains the direction from // //
which the current path most recently arose, in
order to ensure that no // // attempt will
be made to bounce back and forth between two
previously visited // // locations.

// /////////////////////////////////////////////
///////////////////////////////////// boolean
proceed(char matrixMATRIX_SIDEMATRIX_SIDE,
direction startDirection, int
startRow, int startCol, int destRow, int
destCol) int eastPos2 int westPos2
int northPos2 int southPos2 boolean
flag FALSE
27
Maze Solving (Continued)
if ((startRow destRow) (startCol
destCol)) // TERMINATION CONDITION flag
TRUE //
DESTINATION REACHED! else if
(matrixstartRowstartCol ! ' ') //
TERMINATION CONDITION flag FALSE
// DEAD END
REACHED!! else
// RECURSIVE CONTINUATION
eastPos0 startRow eastPos1 startCol
1 westPos0 startRow westPos1
startCol - 1 northPos0 startRow - 1
northPos1 startCol southPos0
startRow 1 southPos1 startCol switch
(startDirection) case north
flag (proceed(matrix,east,eastPos0
,eastPos1,destRow,destCol)
proceed(matrix,north,northPos0,northPos1,destR
ow,destCol)
proceed(matrix,west,westPos0,westPos1,destRow,
destCol)) break
case south flag
(proceed(matrix,east,eastPos0,eastPos1,destRow
,destCol) proceed(matrix,sout
h,southPos0,southPos1,destRow,destCol)
proceed(matrix,west,westPos0,westP
os1,destRow,destCol))
break
28
Maze Solving (Continued)
case east flag
(proceed(matrix,east,eastPos0,eastPos1,destRow
,destCol) proceed(matrix,nort
h,northPos0,northPos1,destRow,destCol)
proceed(matrix,south,southPos0,sou
thPos1,destRow,destCol))
break default
flag (proceed(matrix,south,southPos0,southPos
1,destRow,destCol)
proceed(matrix,north,northPos0,northPos1,destR
ow,destCol)
proceed(matrix,west,westPos0,westPos1,destRow,
destCol)) break
// If flag is true, then the destination WAS //
// reached via the current "start" position. //
if (flag) matrixstartRowstartCol ''
return flag
29
Maze Solving (Continued)
//////////////////////////////////////////////////
/////// // Function printMatrix outputs the
entire maze matrix.// ////////////////////////////
///////////////////////////// void
printMatrix(char matrixMATRIX_SIDEMATRIX_SIDE)
for (int row 0 row lt MATRIX_SIDE row)
for (int col 0 col lt MATRIX_SIDE
col) cout ltlt matrixrowcol cout
ltlt endl cout ltlt endl return
30
Maze Solving (Continued)
Sample maze (in file C\TEMP\maze) -------
--- -- -
- ------
-- ------
- -- --
- -- -- --
-- -
---- -- --
- - - -
- -
----------
Results of running program on sample maze
31
Recursion vs. Iteration
Note that in several of our examples, it would
have been just as easy to implement the
algorithms via iteration (i.e., looping) as it
was to implement them with recursion. In fact,
the use of recursion for these examples is rather
wasteful, forcing the operating system to do
extra work and taking the risk that a stack
overflow will occur.
When To Use Recursion Instead Of Iteration When
a straightforward iterative solution cannot be
found.
32
The Inefficiency of Recursion
One of the big drawbacks to using recursion is
the inherent inefficiency of many recursive
algorithms. For instance, our maze solving
routine frequently revisits coordinates that have
already been determined to be dead ends! On the
other hand, some recursive algorithms (e.g.,
binary search) are vast improvements over
alternative solutions.
How To Measure The Efficiency Of A Recursive
Algorithm Study Math 224 real hard, and then
take CS 240 and 340!
Write a Comment
User Comments (0)
About PowerShow.com