• Labs icon Lab
  • Core Tech
Labs

Guided: Dynamic Memory Management with Pointers in C

This lab will let you practice dynamic memory allocation in two scenarios - (1) reading expenses into a dynamically allocated array and (2) managing a linked list. Practice working with pointers and managing memory by using malloc, free, pass by reference, dereferencing, and other concepts.

Labs

Path Info

Level
Clock icon Beginner
Duration
Clock icon 35m
Published
Clock icon May 09, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge ourΒ privacy policy.

Table of Contents

  1. Challenge

    What is Dynamic Memory? Why do we need Pointers?

    What Is "Dynamic Memory"?

    Dynamic memory is memory that your program asks for at runtime, using functions like malloc().

    Unlike static or automatic memory (like regular variables), dynamic memory:

    • Isn’t automatically allocated when the program starts
    • Isn’t automatically freed when a function ends
    • Must be managed manually by the programmer πŸ‘ˆ That's YOU!

    OK, but why do you need pointers?

    Because when you allocate memory dynamically in C, the only way to refer to that memory is with a pointer πŸ‘ˆ Or else it's lost.

    Here's an example:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *p = (int *)malloc(sizeof(int));  // Allocate memory for one int
    
        if (p == NULL) {
            printf("Memory allocation failed.\n");
            return 1;
        }
    
        *p = 42;  // Store value at the memory address
        return 0;
    }
    

    Pointer Diagram

    Pointer 'p' stores the address of dynamically allocated memory. This diagram shows the two key parts of using a pointer to a single int:

    • 🟦 Stack: The variable p lives here and stores the address 0x2000.
    • 🟩 Heap: The memory at 0x2000 was allocated using malloc, and stores the actual value 42.

    To print the value of 'p':

    printf("The value of *p is: %d\n", *p);      // β†’ 42
    

    To print the memory address p points to:

    printf("The memory address p points to is: %p\n", (void*)p);  // β†’ 0x2000 (example)
    

    To free the memory that p points to:

    free(p);  // Always free heap memory when done
    

    Next: Allocate Memory for an Array of Numbers

    Now that you've reviewed the basics of pointers, next you will create a program that allocates memory for an array of numbers.

    info> In the filetree, there is a solution folder with solution code for each task in case you get stuck.

  2. Challenge

    Create average expenses program

    Add your code to the Expenses.c file in the editor. Check your progress with the Validate button.

    If at any point you also want to compile and run your program, you can do that from the Terminal below the code window.

    First, compile your program with:

    gcc Expenses.c -o Expenses.out
    

    Then you can run your program with:

    ./Expenses.out
    ``` In `Expenses.c`, you are going to create a program that asks the user for a list of their daily expenditures over the past X number of days. Then you are going to tell them their average daily expenses. 
    
    Since the program asks the user how many `days` of expenses they want to enter, you don't know how big the `expenses` array is going to be. You will need to allocate memory for `expenses` depending on what the user enters for the `days` value. 
    
    Remember, in the previous example, **`p` was a pointer to one `int`.**
    
    In `Expenses.c`, **`expenses` is a Pointer to an Array of `float`.**
    You need to allocate a whole block of memory for many floats (how many? Whatever `days` is). In the image below, memory was allocated for 5 days of expenses.
    
    ![Array of floats also showing memory addresses](https://s2.pluralsight.com/code-labs/public/b04ab935-1d50-4818-8eef-d20702b91364/8a70829080196025dbb6-1746130162.png)
    
    This is useful when the size of data isn't known at compile time β€” for example, based on user input.
  3. Challenge

    Get daily expenses from the user

  4. Challenge

    Calculate the average and clean up

    Part 1 is complete - Congratulations on completing your Expenses program!! πŸŽ‰ Feel free to try it out in the terminal.

    Remember you can compile your program with: gcc Expenses.c -o Expenses.out

    Then you can run your program with: ./Expenses.out

    Keep going to learn more about dynamic memory, pointers, and create a Linked List.

  5. Challenge

    Linked Lists Explained

    What Is a Linked List?

    🟩 10 ─▢ 🟦 20 ─▢ 🟦 30 ─▢ 🚫 A linked list is a way of storing a list of items in separate memory blocks, where each item (called a node) points to the next one in the sequence.

    In C, each node contains:

    • 5️⃣ The data (like a number or a name)
    • ➑️ A pointer to the next node

    Why Use a Linked List?

    • βœ… Flexible size You can add or remove elements easily without knowing how many you need in advance (unlike arrays).
    • βœ… Efficient insert/delete You don’t need to shift elements like in arrays. Just update pointers.
    • βœ… Great for dynamic data Perfect when the amount of data is changing (like a contact list, playlist, or task queue).

    Linked List Example in C

    The data and pointer are usually contained inside a struct in C. Here’s what a node might look like:

    typedef struct Node {
        int data;              // The value we’re storing
        struct Node *next;     // Pointer to the next node
    } Node;
    

    What a Linked List Looks Like

    Let me show you a simple linked list with 3 nodes containing the values 10, 20, and 30:

    Linked List Diagram

    Notice at the end of a list, the last node's next pointer points to NULL. That's how you know it's the end.

    Also notice, the head pointer will always point to the front of the list and is an important "handle" to keep track of. Now you can start writing code to manage a Linked List class. Adding a new node to the list is a good place to start.

    First, take a look at the code inside of LinkedList.c. The imports are at the top, followed by the struct Node. Then inside main(), you can see:

    Node* head = NULL;
    

    This is how an empty list is started. As new nodes are added, they will be added at the front of the list by setting the new Node's next pointer equal to head. Then head will become the new Node.

    Now, you're going to code the steps to insert a new node at the beginning of the list with value 2.

    1. Create a new Node with malloc
    2. Set its data to 2
    3. Point its next to the current head of the list
    4. Update the head to point to this new Node
  6. Challenge

    Create a Linked List

  7. Challenge

    Create `addToFront()` function

    Now that you've coded the steps to add a new Node a Linked List, you should abstract out these steps into a function called addToFront().

  8. Challenge

    Print the Linked List

    Now that you've added multiple Nodes to the Linked List, you should print out the entire list.

    To print all the values in the list, you need to:

    • Start at the head
    • Print the current Node’s data
    • Move the current Node to the next pointer
    • Stop when the current Node is NULL (end of list) Congratulations on completing your program!! πŸŽ‰ Your Linked List program is complete, feel free to run it in the terminal.

    Remember you can compile your program with:

    gcc LinkedList.c -o LinkedList.out
    

    Then you can run your program with:

    ./LinkedList.out
    

    During this Code Lab you used dynamic memory and pointers in a few different ways. You:

    • Used malloc() to dynamically allocate memory for a float array
    • Printed memory addresses to visualize the array contents
    • Freed memory using free()
    • Used pointers to connect nodes in a Linked List
    • Used the arrow operator -> to access members of a Linked List Node.

    Congratulations again!! πŸ‘πŸ‘ You did an awesome job sticking through the tutorial β€” this kind of continued learning is exactly what makes great developers πŸ‘πŸ‘

Sarah just finished her PhD in Computer Science and in that process found two loves: inventing things and teaching. Working at Pluralsight allows her to do what she loves and work with some amazing people.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.