Section 2: Arrays and Pointers #
Dates: February 5, 2026 – February 7, 2026
The code for this section can be found here.
Learning Goals 🎯 #
By the end of this section, you will be able to:
- Understand pointer arithmetic, why it’s useful, and how it can be used equivalently with array indexing syntax.
- Draw more detailed memory diagrams using GDB! This will help you understand how variables in your program are stored and connect to each other.
Activity 1: Array Pointer Swap! 👩🔬⚗️ #
In Introduction to Computational Potions, a faulty potion exploded on the professor’s desk as he was grading a student’s concoction! The explosion scattered a neatly stacked pile of papers throughout the class, which were grouped together by the memory address that they lead to. Using your computer systems skills, help the professor organize the papers back together!
int a[8]; // <- starts at address 0x8000
char b[32]; // <- starts at address 0xff00
This activity uses these two arrays. (We’ve already used GDB to write the address in memory where each one starts.)
Instructions #
- Everyone will be given a slip of paper with an expression written on it. Each expression uses the two variables defined above to calculate a memory address.
- We’ll walk through two example expressions together.
- Now, work together with your table to calculate everyone’s memory addresses, and write it on your slip.
- Move around the room and find everyone else whose slip resulted in the same memory address as yours.
Activity 2: GDB and Memory Layouts #
Now that hopefully you’ve worked with GDB in Snake, let’s get more GDB practice with memory layouts! 🙂
As a reminder, here are helpful GDB commands!
Below are a list of common commands and what they do (you can reference the full GDB guide here, which is also on the course website):
| Command | Shortcut | Description |
|---|---|---|
gdb [program] | — | Starts GDB on your executable file (your compiled .c file). If you don’t see it, run make. |
layout src | la src | Formats your code file so you can easily read what line(s) of code GDB is about to execute. |
breakpoint [line # or function name] | b | Sets a breakpoint at the given location. When running gdb, execution will stop before this line. |
run | r | Executes all lines of code from the beginning of the file until the first breakpoint (or the end of the file if there aren’t any). |
continue | c | Executes all lines of code from wherever execution stopped until the next breakpoint (or end of file) |
backtrace | bt | Prints out a debug message of all active function calls that have led to the current state in the file, including when execution errors or crashes. |
print [variable name or expression] | p | Prints out the value of a variable or expression involving a variable (such as a dereference). |
next | n | Executes the current line. If this is a function call, executes all functionality within the function. |
step | s | Executes the current line. If this is a function call, stop before executing lines inside the function. |
#include <stdlib.h>
typedef struct ListNode {
struct ListNode* next;
int value;
} ListNode;
ListNode* createHead(int value) {
ListNode node;
node.value = value;
node.next = NULL;
return &node;
}
int main() {
// Part A
int x = 10;
int* y = &x;
// Part B
ListNode* a = malloc(sizeof(ListNode));
(*a).value = 20;
(*a).next = NULL;
// Part C
ListNode* b = malloc(sizeof(ListNode));
(*b).value = 30;
(*b).next = NULL;
(*a).next = b;
// Bonus
ListNode* head = createHead(40);
(*head).next = a;
// Cleanup
free(head);
free(a);
free(b);
return 0;
}
Instructions #
For Parts A-C: #
Work with your group to draw a memory diagram on the whiteboard.
- Draw a memory diagram of allocated memory. Your diagram should include:
- All variables in
mainand their values. - All dynamically allocated memory (from
malloc). - The stack and heap sections of memory clearly labeled.
- All variables in
Here’s an example of what your diagram could look like (note that the addresses here are just examples; your actual addresses will differ):

- Use GDB to find the actual addresses of each piece of memory to include in your diagram.
- Do not worry about addresses changing on separate program runs; just pick one run and use those addresses.
For the Bonus: #
The bonus code has a bug! Try and find it, and if you do try and make a memory diagram for the code similar to parts A-C.