24 Intermediate C Programming
Frame Symbol Address Value
f2
u 102 21
b 101 6
a 100 5
Note that the values of a and b in f2 have not changed.
Even though the same symbol may appear in different frames, the same name cannot
be defined twice within the same frame. The following program is invalid because a is used
as both an argument and a local variable, in the same function:
int f1 ( in t a , in t b )1
{2
int k = 3;3
int m = -5;4
int a = k + 2; // cannot define a twice5
int b = m - 1;6
return (k + m) ;7
}8
9
void f2 ( void)10
{11
int a = 5;12
int b = 6;13
int u;14
u = f1( a + 3, b - 4) ;15
// some additiona l code16
}17
In review, this chapter explains the concept of the call stack, which is used whenever a
function is called. The call stack stores the return location, the value address, the arguments,
and the local variables for each function.
2.5 Exercises
This book has two types of homework: exercises and programming problems. Exercises
are problems that do not require writing programs—they are “paper-and-pencil” problems.
Programming problems, obviously, are done on a computer.
Understanding the call stack is one of the most essential skills for programmers. If you
want to understand C programs (and many other programming languages), then a solid
understanding about the call stack is necessary.
2.5.1 Draw Call Stack I
int f1 ( in t k , in t m )1
{2
int y;3
y = k + m;4
return y;5
Stack Memory 25
}6
7
void f2 ( void)8
{9
int a = 83;10
int c = -74;11
c = f1(a , c);12
/* RL */13
}14
Draw the call stack
before f1 is called.
when the program has finished line 4.
when the program has finished f1 and the top frame has been popped.
2.5.2 Draw Call Stack II
void f1 ( i n t k , int m)1
{2
int y;3
y = k;4
k = m;5
m = y;6
}7
8
void f2 ( void)9
{10
int a = 83;11
int c = -74;12
f1 (a , c );13
/* RL */14
}15
Draw the call stack
when the program has entered f1 and finished line 4. What are the values of k and m?
when the program has finished line 6, and before f1’s frame is popped. What are the
values of k and m?
when the program has finished f1 and f1’s frame has been popped. What are the
values of a and c?
2.5.3 Addresses
How can a programmer control the address of a variable?
If the same program runs multiple times, will the address of the same variable be the
same?
Are the addresses of an array’s elements contiguous or scattered?
26 Intermediate C Programming
2.6 Answers
2.6.1 Draw Call Stack I
before calling f1
Frame Symbol Address Value
f2
c 101 74
a 100 83
finished line 4
Frame Symbol Address Value
f1
y 106 9
m 105 74
k 104 83
Value Address 103 101
Return Location 102 line 13
f2
c 101 74
a 100 83
after f1’s frame popped
Frame Symbol Address Value
f2
c 101 9
a 100 83
2.6.2 Draw Call Stack II
finished line 4
Frame Symbol Address Value
f1
y 105 83
m 104 74
k 103 83
Return Location 102 line 14
f2
c 101 74
a 100 83
finished line 6
Frame Symbol Address Value
f1
y 105 83
m 104 83
k 103 74
Return Location 102 line 14
f2
c 101 74
a 100 83
The values of k and m have been swapped.
Stack Memory 27
f1’s frame popped
Frame Symbol Address Value
f2
c 101 74
a 100 83
The values of a and c have not changed.
2.6.3 Addresses
A programmer cannot control the address of a variable.
If the same program runs multiple times, the address of the same variable will likely
be different.
The addresses of an array’s elements are contiguous.
2.7 Examine the Call Stack with DDD
Type the following program into an editor and save it under the name p1.c
/* p1 .c */1
#in clude < stdio .h >2
#in clude < stdlib .h >3
int g1 ( in t a , in t b )4
{5
int c = (a + b) * b;6
printf (" g1 : a = %d , b = %d , c = %d n" , a , b , c);7
return c;8
}9
10
int g2 ( in t a , in t b )11
{12
int c = g1 (a + 3 , b - 11) ;13
printf (" g2 : a = %d , b = %d , c = %d n" , a , b , c);14
return c - b ;15
}16
17
int main ( i n t argc , char * * argv )18
{19
int a = 5;20
int b = 17;21
int c = g2 (a - 1 , b * 2) ;22
printf (" main : a = %d , b = %d , c = %d n" , a , b , c);23
return EXIT _SUCCES S ;24
}25
Do not worry about fully understanding argv in the main function yet; this will be discussed
later. Create the executable using the following command in a Linux terminal:
$ gcc -g -Wall -Wshadow p1.c -o p1
28 Intermediate C Programming
This uses gcc to convert the source file of the C program (p1.c), into an executable file that
the computer can understand. Adding -g enables debugging so that we can examine the
call stack. Adding -Wall and -Wshadow enables warning messages. Shadow variables will be
explained in Section 4.1. Warning messages are sometimes benign, but they usually indicate
deeper problems in the code. It is good practice to always enable warning messages, and to
act on gcc’s advice. The name of the output file (i.e., the executable file) is specified by -o.
In this example, p1 is the output of the gcc command and, thus, is the executable file (i.e.,
the program). It can be run in the terminal by typing:
$ ./p1
The output should be the same as the following:
g1: a = 7, b = 23, c = 690
g2: a = 4, b = 34, c = 690
main: a = 5, b = 17, c = 656
To view the call stack, we will need to start the debugger. In this example, we will use
DDD (Data Display Debugger). DDD is a graphical user interface for the GDB debugger.
Start DDD, go to the menu and click
File - Open Program - select p1 - Open
Here, we have selected the executable program, not the .c file. The debugger will automat-
ically find the .c file based on information that gcc leaves in the executable. This is useful
when debugging a program that uses multiple source files.
Set breakpoints at the two functions g1 and g2 with the following commands after the
(gdb) prompt in the bottom window:
(gdb) b g1
(gdb) b g2
The command b g1 instructs DDD to set a breakpoint when the function g1 starts.
When the program reaches the first line of g1, the program will stop and you will get a
chance to check the status of the program. The command b g2 instructs DDD to similarly
set a breakpoint when the function g2 starts.
Execute the program by typing the following command at the (gdb) prompt:
(gdb) run
The program will start, and then pause at the breakpoint of function g2. Why does the
program stop at g2, not g1? Because main calls g2, so g2 is encountered before g1. If
several breakpoints are set, the program will pause at the breakpoints based on the order
in which they are executed, not the order in which they are set. In this example, although
the breakpoint at g1 is set first, the program executes g2 first. Thus, the program pauses
at the breakpoint g2 first.
To continue the program, type the following command:
(gdb) continue
The program will continue executing and then pause at the next breakpoint, located at
function g1. The call stack can be viewed by asking for the backtrace. This is done with
the following command:
(gdb) bt
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset