# Pointers and References — C++

Source: https://www.skillbyai.com/en/cpp/m-pointers

> Use pointers and references safely and avoid dangling references.

## Two ways to refer to an object

A **reference** (`int& r = x;`) is an alias for an existing object: it must be initialised, cannot be **reseated** to refer to something else and is never null. Use references for function parameters and for giving access to existing objects. A **pointer** (`int* p = &x;`) is an object holding an address: it can be null (**`nullptr`**, never `NULL` or `0` in modern code), reassigned, and must be **dereferenced** with `*p` or `p->member`. Use pointers when "no object" is a valid state or when you need to re-point. **Pointer arithmetic** moves through arrays (`p + 1` is the next element), but going out of bounds is undefined behaviour. `const` interacts with pointers in two places: `const int* p` (pointer to const data) versus `int* const p` (const pointer). The main danger with both is **dangling**: a pointer or reference to an object whose lifetime has ended, such as returning a reference to a local variable, or keeping a pointer into a `std::vector` that later **reallocates**. Raw pointers in modern code should be **non-owning** observers; ownership belongs to smart pointers and containers.

## References, pointers and two dangling bugs

Both bugs compile; both are undefined behaviour at run time.

```cpp
#include <string>
#include <vector>

void basics() {
    int x = 10;
    int& r = x;          // alias: r and x are the same object
    r = 20;              // x is now 20

    int* p = &x;         // address of x
    *p = 30;             // x is now 30
    p = nullptr;         // pointer can be null and reseated; a reference cannot
}

const std::string& bad_name() {
    std::string local = "temporary";
    return local;        // BUG: returns a reference to a destroyed local (dangling)
}

void bad_vector() {
    std::vector<int> v{1, 2, 3};
    int* first = &v[0];
    v.push_back(4);      // may reallocate and move all elements
    // *first = 99;      // BUG: first may now dangle
}
```

## A nickname and an address slip

A reference is a nickname for a person: always refers to the same person and cannot exist without them. A pointer is a slip of paper with an address: it can be blank, rewritten, or still point to a house that has been demolished.

**Quiz:** Which statement about C++ references is true?

- [ ] A reference can be null
- [ ] A reference can be reseated to refer to another object
- [ ] A reference stores a copy of the object
- [x] A reference must be initialised and always refers to the same object

*Answer:* A reference must be initialised and always refers to the same object. References are aliases bound at initialisation; they cannot be null or reseated.
