> For the complete documentation index, see [llms.txt](https://learncpp.benntan.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learncpp.benntan.com/memory-and-ownership/arrays-and-strings.md).

# Arrays & Strings

Thus far, pointers pointed to a singular variable. But what if we have multiple values stored together (exactly, like an array!)

### Arrays

To declare an array:

{% code title="" %}

```cpp
int arr[3] = {10, 20, 30}; // array
int* p_arr = arr;          // pointer to array
```

{% endcode %}

Visually, this is how an array is represented:

<figure><img src="https://1407522535-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMKUM5bJORzyfGuRLJG7%2Fuploads%2FlFsr34qQv5tXnXer2WI3%2FScreenshot%202026-04-05%20at%2012.46.02%E2%80%AFAM.png?alt=media&amp;token=3c5de667-eebc-4067-ac54-034ce105c551" alt=""><figcaption></figcaption></figure>

Note that:

* All 3 elements sit **side-by-side** (i.e there exists no gaps between them). This is what we mean by **contiguous memory.**
* You may also have noticed that the difference between each memory address is 4 bytes. This because (usually) `int` occupies 4 bytes.

### Pointer Arithmetic

Since `p_arr`  stores the address of the first element, you can access `arr[0]` via dereferencing `*p_arr`. &#x20;

What about `arr[1]`? The cool thing about pointer arithmetic is that it's **type-aware,** you can simply perform `(p_arr + 1)` to move forward by 1 element of type `int` (i.e 4 bytes).

Functionally,

<table><thead><tr><th width="243.72222900390625">Operation</th><th>Result</th></tr></thead><tbody><tr><td><code>*p_arr</code></td><td>Move <code>p_arr</code> by 0 bytes, dereference to get <code>arr[0]</code></td></tr><tr><td><code>*(p_arr + 1)</code></td><td>Move <code>p_arr</code> by 4 bytes, dereference to get <code>arr[1]</code></td></tr><tr><td><code>*(p_arr + 2)</code></td><td>Move <code>p_arr</code> by 8 bytes, dereference to get <code>arr[2]</code></td></tr></tbody></table>

Note that `arr` also decays into a pointer to the first element that shares the same memory address as `p_arr`, hence operations that can be done with `arr` can also be done with `p_arr`&#x20;

{% code title="main.cp" %}

```cpp
#include <iostream>

int main() {
    int arr[3] = {10, 20, 30};
    std::cout << arr[0] << std::endl; // 10
    std::cout << arr[1] << std::endl; // 20
    std::cout << arr[2] << std::endl; // 30
    
    std::cout << *(arr + 0) << std::endl; // 10
    std::cout << *(arr + 1) << std::endl; // 20
    std::cout << *(arr + 2) << std::endl; // 30
    
    int* p_arr = arr;
    std::cout << *(p_arr + 0) << std::endl; // 10
    std::cout << *(p_arr + 1) << std::endl; // 20
    std::cout << *(p_arr + 2) << std::endl; // 30
}
```

{% endcode %}

<details>

<summary>😎 Cool Fun Fact</summary>

We've learnt that we can access `arr[0]` via `*(arr + 0)`. Since addition is commutative, `*(arr + 0) == *(0 + arr)`, hence `0[arr]` works too!

{% code title="main.cpp" %}

```cpp
#include <iostream>
int main()
{
    int arr[3] = {10, 20, 30};
    std::cout << 1 [arr] << std::endl;
    std::cout << arr[1] << std::endl;
}
```

{% endcode %}

</details>

### Strings

Fundamentally, a string is simply an *array* of characters ending with a special character `\0` (i.e null terminator)

The usual pointer arithmetic rules that we've learnt above apply too.

{% code title="main.cpp" %}

```cpp
#include <iostream>

int main() {
    char str[] = "hello";
    std::cout << str[0] << std::endl;        // 'h'
    std::cout << *(str + 1) << std::endl;    // 'e'
    
    char* str2 = "world";
    std::cout << str2[0] << std::endl;        // 'w'
    std::cout << *(str2 + 1) << std::endl;    // 'o'
}
```

{% endcode %}

Notice when we compile, we get a warning:

<figure><img src="https://1407522535-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMKUM5bJORzyfGuRLJG7%2Fuploads%2FMpd1gHlJ92BLa1sK7udj%2FScreenshot%202026-04-05%20at%201.17.41%E2%80%AFAM.png?alt=media&amp;token=9a6d054e-e282-488a-ac94-6ced03a517fa" alt=""><figcaption></figcaption></figure>

<details>

<summary>😕 Why the warning for <code>char* str2</code> but not <code>char str[]</code> ?</summary>

`"hello"`  is a string literal stored in read-only memory.

`char[]` has no issues since it copies the string literal onto its own array on the stack.

`char *` is pointing to the same string literal in read-only memory. Writing to it causes undefined behaviour hence the warning.

In fact, if you try compiling the program with stricter flags: `clang++ -std=c++17 -Wall -Wextra -pedantic-errors main.cpp -o hello-world`, the compiler rejects the code entirely.

<figure><img src="https://1407522535-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMKUM5bJORzyfGuRLJG7%2Fuploads%2F2Q7C2MtUyScoYSkt1JOT%2FScreenshot%202026-04-05%20at%201.20.16%E2%80%AFAM.png?alt=media&amp;token=42200d2b-3077-4b71-b154-865f5c11172a" alt=""><figcaption></figcaption></figure>

To squash this, we can use `const char *`  to assert that we are not going to modify the string.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://learncpp.benntan.com/memory-and-ownership/arrays-and-strings.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
