Skip to content
Laviyx Learn

Try

C++ References, Pointers and Memory Practice

Practise references, pointers, nullptr checks, pointer arithmetic and smart pointers in C++.

Intermediate6 problemsUpdated

Review first: References, Pointers, Dynamic Memory: new and delete, Smart Pointers

  1. 1.Change elements through references

    Intermediate

    Write void double_all(std::vector<int>& v) that doubles every element in place, and use it on {3, 7, 10}.

    Show hint

    Take the vector by reference, and loop with int& so you change the real elements.

    Show solution
    C++
    #include <iostream>
    #include <vector>
    
    void double_all(std::vector<int>& v) {
        for (int& x : v) {
            x *= 2;
        }
    }
    
    int main() {
        std::vector<int> v = {3, 7, 10};
        double_all(v);
        for (int x : v) std::cout << x << ' ';
        std::cout << '\n';
    }
    Output
    6 14 20
  2. 2.Swap with pointers

    Intermediate

    Write void swap_ptr(int* a, int* b) that swaps the values the two pointers point to (doing nothing if either is null). Swap x = 5 and y = 12.

    Show hint

    Dereference with *a and *b. Pass the addresses with &x and &y.

    Show solution
    C++
    #include <iostream>
    
    void swap_ptr(int* a, int* b) {
        if (a == nullptr || b == nullptr) return;
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    
    int main() {
        int x = 5;
        int y = 12;
        swap_ptr(&x, &y);
        swap_ptr(&x, nullptr);   // safely ignored
        std::cout << x << ' ' << y << '\n';
    }
    Output
    12 5
  3. 3.Walk an array with a pointer

    Intermediate

    Sum the C-style array int data[] = {4, 8, 15, 16, 23, 42}; using a pointer that starts at the first element and moves forward until it reaches one past the end.

    Show hint

    data + 6 points one past the last element. Loop for (const int* p = data; p != data + 6; ++p).

    Show solution
    C++
    #include <iostream>
    #include <iterator>
    
    int main() {
        int data[] = {4, 8, 15, 16, 23, 42};
        const int* end = data + std::size(data);
    
        int sum = 0;
        for (const int* p = data; p != end; ++p) {
            sum += *p;
        }
        std::cout << sum << '\n';
    }
    Output
    108
  4. 4.Return a pointer or nullptr

    Intermediate

    Write int* find_first_negative(std::vector<int>& v) that returns a pointer to the first negative element, or nullptr if there is none. Use it to set the first negative value in {4, -2, 7, -9} to 0, and show that searching {1, 2} returns nullptr.

    Show hint

    Return &v[i] when you find a match. Always check the result against nullptr before using it.

    Show solution
    C++
    #include <iostream>
    #include <vector>
    
    int* find_first_negative(std::vector<int>& v) {
        for (int& x : v) {
            if (x < 0) return &x;
        }
        return nullptr;
    }
    
    int main() {
        std::vector<int> a = {4, -2, 7, -9};
        if (int* p = find_first_negative(a)) {
            *p = 0;
        }
        for (int x : a) std::cout << x << ' ';
        std::cout << '\n';
    
        std::vector<int> b = {1, 2};
        std::cout << std::boolalpha << (find_first_negative(b) == nullptr) << '\n';
    }
    Output
    4 0 7 -9
    true

    The pointer is only valid while the vector is unchanged. Adding elements could reallocate the vector and leave the pointer dangling.

  5. 5.Transfer ownership with unique_ptr

    Intermediate

    Create a std::unique_ptr<std::string> holding "report.pdf", move it into a second unique_ptr, and print whether the first is now empty and what the second holds.

    Show hint

    Create with std::make_unique, and move with std::move. A moved-from unique_ptr is null.

    Show solution
    C++
    #include <iostream>
    #include <memory>
    #include <string>
    #include <utility>
    
    int main() {
        auto first = std::make_unique<std::string>("report.pdf");
        auto second = std::move(first);
    
        std::cout << std::boolalpha << (first == nullptr) << '\n';
        std::cout << *second << '\n';
    }
    Output
    true
    report.pdf
  6. 6.Watch the reference count

    Intermediate

    Create a std::shared_ptr<int> holding 42. Print its use_count(), then create a copy inside a block and print the count inside and after the block.

    Show hint

    Copying a shared_ptr adds an owner; destroying the copy at the end of the block removes one.

    Show solution
    C++
    #include <iostream>
    #include <memory>
    
    int main() {
        auto value = std::make_shared<int>(42);
        std::cout << value.use_count() << '\n';
        {
            std::shared_ptr<int> copy = value;
            std::cout << copy.use_count() << '\n';
        }
        std::cout << value.use_count() << '\n';
    }
    Output
    1
    2
    1