This worksheet covers a few elements of pointers in C that will be used in this course. You should have seen this material in the introductory classes (or from the classes that were used to waive the introductory classes).
Questions and Completion
There is nothing to hand in for the worksheet, but you should definitely work through it in order to prepare for the quiz and homework.
If you have questions as you go through this worksheet, please feel free to post them on the discussion forum.
C Memory Allocation and Pointers
Pointers
Consider the following C program.
Replace the comments with code, so that the value of x is 10 when it is printed.
#include <stdio.h>
#include <stdlib.h>
void update (int* p) {
/* TODO */
}
int main () {
int x = 5;
update (/* TODO */);
printf ("%d\n", x);
}Allocation Location
Consider the following C program.
#include <stdio.h>
#include <stdlib.h>
int x = 5;
int main () {
int y = 10;
int* p = (int*) malloc (sizeof (int));
}Answer the following questions:
Where in memory is
xallocated?Where in memory is
yallocated?Where in memory is
pallocated?Where in memory is
ppointing to?
Call-Stack Allocation
Consider the following C program.
#include <stdio.h>
#include <stdlib.h>
void countdown (int n) {
if (n <= 0) {
printf ("done\n");
} else {
printf ("counting down\n");
countdown (n - 1);
}
}
int main () {
countdown (5);
}When it is executed:
What will be printed?
What is the maximum number of activation records (also known as stack frames) on the call stack at one point during execution?
Solution: Call-Stack Allocation
Dangling Pointer
Consider the following two C programs. Which one of these programs is problematic and why?
#include <stdio.h>
#include <stdlib.h>
int foo (int n) {
int result = 2 * n;
return result;
}
int main () {
int x = foo (5);
int y = foo (7);
printf ("%d\n", x);
printf ("%d\n", y);
}#include <stdio.h>
#include <stdlib.h>
int* foo (int n) {
int result = 2 * n;
return &result;
}
int main () {
int* p = foo (5);
int* q = foo (7);
printf ("%p %d\n", p, *p);
printf ("%p %d\n", q, *q);
}Solutions
Solution: Pointers
#include <stdio.h>
#include <stdlib.h>
void update (int* p) {
*p = 10;
}
int main () {
int x = 5;
update (&x);
printf ("%d\n", x);
}$ gcc -o pointers-01-solution pointers-01-solution.c
$ ./pointers-01-solution
10
Solution: Allocation Location
Global memory.
In an /activation record/ for
main(also known as /stack frame/) stored on the /call stack/.In an /activation record/ for
main(also known as /stack frame/) stored on the /call stack/.On the heap.
Solution: Call-Stack Allocation
This is printed.
counting down counting down counting down counting down counting down doneThere are at least 8 activation records on the call stack when
doneis printed byprintf. There may be more since we do not know the implementation ofprintf.maincountwithn= 5countwithn= 4countwithn= 3countwithn= 2countwithn= 1countwithn= 0printf
Solution: Dangling Pointer
The first program is fine.
The second program is problematic because p is a /dangling pointer/ after foo returns. That is, p contains a pointer to an area of memory that is not defined, and when it is dereferenced (using *p) the behavior is not guaranteed: it might be 10, some other value, or crash the program. This happens because the result variable is allocated in the activation record for foo, and the address of result is returned from foo, but the activation record for foo is deallocated (hence the memory storing result is also deallocated) when foo returns.