Functions: Pass-by-Pointer vs. Pass-by-Reference

Sticky Notes vs. Nicknames

Visualizing Parameter Passing

In C++, modifying data from within a function requires understanding how the function accesses that data in memory. We use two primary mental models:

Welcome. To understand how C++ handles data in functions, let's look at memory. Imagine this box is a variable. Passing by pointer is like giving someone a sticky note with the box's address. They use it to find and change the contents. Passing by reference, however, is like giving the box a nickname. You're talking about the exact same box, just using a different name. With a pointer, the 'sticky note' is its own variable. You can even cross out the address and point it at a different box entirely. A reference is locked. Once you decide that 'y' is a nickname for 'x', it stays that way for the duration of the function.

Pass-by-Pointer: The Manual Approach

Using the Address-Of and Dereference Operators

When passing by pointer, we use * in the signature to indicate a pointer and & at the call site to get the address.

void update(int* ptr) {
  if (ptr != nullptr) {
    *ptr = 42;
  }
}

Let's look at the syntax. In the function signature, the asterisk indicates that 'ptr' holds an address. When we call the function, we use the 'address-of' operator to send that specific location. Because pointers can be null, we must always include a safety check before we dereference to change the value. When we say 'star ptr equals 42', we are following the address on our 'sticky note' and changing the value inside that memory box.

Pass-by-Reference: The Modern Default

Clean Syntax and Safety Guarantees

Passing by reference is the modern C++ standard for 'out' parameters. It uses the & symbol in the signature but behaves like a normal variable inside the function.

void update(int& ref) {
  ref = 42;
}

Notice how much cleaner this looks. The ampersand in the signature tells C++ this is a reference. Inside the function, we treat 'ref' like a normal variable. Unlike pointers, references are guaranteed to point to valid data, so no null check is required.

Pointer vs. Reference: Sorting the Facts

Which is Which?

Drag the characteristics to the correct column. Think about nullability, syntax, and reassignment.

Let's test your understanding of the differences. Drag each feature to the correct category: Pass-by-Pointer or Pass-by-Reference. That's correct! That feature is a key characteristic of this method. Not quite. Remember, pointers are more flexible but require more care, while references are safer and more rigid.

Designing a Safe API

Choose Your Approach

You are designing a function to update a player's score. Sometimes a player might not have a score record yet (it's optional). Should you use a pointer or a reference?

Consider this design challenge. You need to update a score, but the score record might be missing. Which method allows you to handle a 'no value' state safely?

Debug the Outage

Find the Memory Error

The following code is causing a segmentation fault. Analyze the function and fix the bug in the text area below.

void process(int* val) {
  *val = 100;
}

This code looks simple, but it's dangerous. It's crashing when no data is provided. Correct the function to make it safe.

Summary: How to Choose

Best Practices Checklist

To wrap up, remember the hierarchy of choice. Start with references; they are your safe, modern default. Only reach for raw pointers when you specifically need the flexibility of a null state or the ability to re-point your variable. Master these, and you'll write much more robust C++ code.