Section 1: Pointers and Debugging #
Dates: January 29, 2026 – January 31, 2026
Learning Goals 🎯 #
By the end of this section, you will be able to:
- Identify pointers/references (as opposed to values) and understand how to leverage them in C. This will help you when completing the course assignments (which all involve pointer-based code in C) and give you a better understanding of how computer memory is organized at a low level.
- Feel comfortable running GDB and using it to step through simple programs. This will give you valuable debugging skills that will help you complete course assignments more efficiently, and provide skills at using a tool that is widely used in industry.
How section works #
Welcome to CS300 section! We release section material via the CS 300 website (where you’re reading this now) and the cs300-s26-section repository. You’ll want to obtain a local copy with git clone git@github.com:csci0300/cs300-s26-section.git.
Section instructors will work through the section material at their own pace, stopping at activities, questions, and discussions so students can work through the material together. It’s best if you bring your laptop. Notes from most section activities will be available here after all sections for that week have been held.
Section is meant to be interactive! It works best when students ask questions and help each other out, and sometimes instructors will take the section in an unexpected direction based on student requests. Please speak up — if you have questions from lecture, section is the perfect time to ask! 🙂
You can find the code for this section here.
Debugging Brainstorm #
With your partner, think about your current debugging process.
In the past, when you’ve encountered a bug in a program (e.g., in your intro courses), how did you go about:
- figuring out where the bug is coming from; and
- deciding how to go about fixing the bug?
Take a few notes on techniques you’ve used successfully (or unsuccessfully!) in the past.
The Debugger’s Tool: GDB ⚡️⚡️ #
GDB (GNU Debugger) is an essential resource for debugging in this course, and getting comfortable with using it will save you time during projects. GDB is also very widely used in industry to debug code in all sorts of languages (not just C), so learning it now will help you in future courses and jobs!
GDB allows you to run through your code line-by-line (or by sections that you create) and print useful information. Once you begin debugging in Question 1, we’ll provide you with a list of helpful commands.
Activity 1: Intro to GDB! 🧙 #
Here’s a program that performs some pointer operations to increment an integer variable, but contains a bug. Together, we’ll consider the following questions:
- What is the goal of this program?
- What actually happens when you run it?
- Why does this happen?
We’ll use GDB as a tool to help us answer these questions.
#include <assert.h>
// increments an integer by one
// Is this pass by value or reference? 🤔
void increment_by_one(int* x) {
*x = *x + 1;
}
int main () {
int my_number = 1;
increment_by_one(my_number);
// my_number should be 2 now
printf("my number is %d\n", my_number);
}
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. |
Activity 2: Harry Pointer and the Debugger’s Tool 👨💻🪄 #
As part of his Fundamentals of Computer Magic class, Harry Pointer wrote a program to swap values between variables, but he complains that his program isn’t working as he intended. Using your new GDB skills, go through Harry’s program and see if you can figure out what’s going wrong.
Here are some helpful tips Harry wrote in his notebook:
- Try drawing a diagram of where the pointers are pointing and then work through the program. How can you use GDB to see how the pointers change during the swap?
- If you think you see what’s wrong, how can you use GDB to confirm your thoughts?
#include <stdio.h>
int main() {
int val_1 = 5;
int* ptr_1 = &val_1;
int** ptr_ptr_1 = &ptr_1;
int val_2 = 3;
int* ptr_2 = &val_2;
int** ptr_ptr_2 = &ptr_2;
printf("val_1 is %d\n", **ptr_ptr_1);
printf("val_2 is %d\n", **ptr_ptr_2);
// Swap the values in the double pointers so that val_1 is 3 and val_2 is 5.
printf("Swapping values...\n");
*ptr_ptr_1 = ptr_2;
*ptr_ptr_2 = ptr_1;
printf("val_1 is %d\n", **ptr_ptr_1); // Should be 3 after swapping
printf("val_2 is %d\n", **ptr_ptr_2); // Should be 5 after swapping
}