Ch5.12: Pointers with vector, array, and string
Overview
Modern C++ containers provide safe, convenient abstractions over raw memory.
However, the three major contiguous containers —
::fast_io::vector, ::fast_io::array, and
::fast_io::string — all expose raw pointers when needed.
In this chapter, you will learn:
- how pointers interact with
::fast_io::vector - how pointers interact with
::fast_io::array - how pointers interact with
::fast_io::string - what
.data()returns - what
.c_str()returns - why these containers guarantee contiguous storage
- how pointer arithmetic works with container storage
- how
::std::to_addressextracts raw pointers from iterators
1. ::fast_io::vector and pointers
::fast_io::vector<T> stores its elements in a contiguous block
of memory. This means:
- the elements are laid out like a C‑style array
- pointer arithmetic works exactly as with C‑style arrays
v.data()returns a pointer to the first elementv.index_unchecked(pos)provides unchecked element accessv.front_unchecked()provides unchecked access to the first elementv.back_unchecked()provides unchecked access to the last element
::fast_io::vector<int> v{1, 2, 3, 4};
int *p = v.data(); // pointer to v[0]
int *q = p + 2; // points to v[2]
int a = v.index_unchecked(1); // unchecked v[1]
int b = v.front_unchecked(); // unchecked v[0]
int c = v.back_unchecked(); // unchecked v[3]
⚠️ Unchecked access never performs bounds checking.
Note: Bounds checking in fast_io is usually extremely cheap.
When an out‑of‑range access is detected, fast_io simply calls
fast_terminate() immediately, without printing diagnostics or
performing expensive error handling. This makes checked access fast while
still providing safety.
2. ::fast_io::array and pointers
::fast_io::array<T, N> is a fixed‑size container that behaves
like a safer C‑style array.
It provides:
- contiguous storage
- bounds‑checked
[]access index_unchecked(pos)for intentionally unchecked accessfront_unchecked()for unchecked access to the first elementback_unchecked()for unchecked access to the last element.data()returning a pointer to the first element
::fast_io::array<int, 3> a{10, 20, 30};
int *p = a.data(); // pointer to a[0]
int *q = p + 1; // points to a[1]
int x = a.index_unchecked(2); // unchecked a[2]
int y = a.front_unchecked(); // unchecked a[0]
int z = a.back_unchecked(); // unchecked a[2]
⚠️ Unchecked functions never perform bounds checking.
Note: Bounds checking in fast_io is extremely cheap,
because fast_terminate() is the only action taken on failure.
Unlike C‑style arrays, ::fast_io::array allows size 0.
3. ::fast_io::string and pointers
::fast_io::string stores characters in a contiguous block of memory.
This means:
s.data()returns a pointer to the first characters.c_str()returns a null‑terminated pointer- pointer arithmetic works exactly like with
char[] s.index_unchecked(pos)provides unchecked character accesss.front_unchecked()provides unchecked access to the first characters.back_unchecked()provides unchecked access to the last character
::fast_io::string s{"Hello"};
char *p = s.data(); // pointer to 'H'
char const *q = s.c_str(); // pointer to 'H', null-terminated
char a = s.index_unchecked(1); // unchecked 'e'
char b = s.front_unchecked(); // unchecked 'H'
char c = s.back_unchecked(); // unchecked 'o'
⚠️ Unchecked access does not validate bounds.
Note: Bounds checking in fast_io is extremely cheap,
because fast_terminate() is called immediately on failure.
Reminder:
s.data() may not be null‑terminated.
s.c_str() is always null‑terminated.
4. Contiguous storage guarantees
All three containers guarantee that their elements are stored contiguously:
::fast_io::vector::fast_io::array::fast_io::string
This means pointer arithmetic is valid as long as you stay within bounds.
int *p = v.data();
int *end = p + v.size(); // one past the end
This is identical to how C‑style arrays behave.
5. Containers do not decay
C‑style arrays decay automatically in most expressions. Containers do not.
int a[3]{1,2,3};
int *p = a; // decay
But:
::fast_io::vector<int> v{1,2,3};
// int *p = v; // ❌ does not compile
You must explicitly request a pointer using .data().
6. Pointer arithmetic with container storage
Once you obtain a pointer from .data(), pointer arithmetic works
exactly as with C‑style arrays.
int *p = a.data();
int *q = p + 2; // points to a[2]
The same applies to ::fast_io::string:
char *p = s.data();
char *q = p + 4; // points to 'o'
As always, going out of bounds is undefined behavior.
7. ::std::to_address and container iterators
::std::to_address is the universal way to obtain a raw pointer from
anything that behaves like a pointer.
- raw pointers
- container iterators
- pointer-like objects
This is important because container iterators are not raw pointers, even though they behave like them.
Example: ::fast_io::vector
auto it = v.begin();
int *p = ::std::to_address(it);
Example: ::fast_io::array
auto it = a.begin();
int *p = ::std::to_address(it);
Example: ::fast_io::string
auto it = s.begin();
char *p = ::std::to_address(it);
::std::to_address is the modern, standard‑approved way to extract a
raw pointer from an iterator.
8. Summary table
| Container | Contiguous? | Pointer from .data() | Null-terminated? | Decay? | Unchecked access? |
|---|---|---|---|---|---|
::fast_io::vector<T> |
✔ yes | T* |
❌ no | ❌ no | ✔ index/front/back_unchecked() |
::fast_io::array<T,N> |
✔ yes | T* |
❌ no | ❌ no | ✔ index/front/back_unchecked() |
::fast_io::string |
✔ yes | char* |
✔ via .c_str() |
❌ no | ✔ index/front/back_unchecked() |
Key takeaways
::fast_io::vector,::fast_io::array, and::fast_io::stringall provide contiguous storage..data()returns a pointer to the first element..c_str()returns a null‑terminated pointer for::fast_io::string.- Containers do not decay; you must call
.data(). - Pointer arithmetic works on container storage exactly like C‑style arrays.
index_unchecked(),front_unchecked(), andback_unchecked()provide fast, unchecked access.- Bounds checking in
fast_iois extremely cheap becausefast_terminate()is used. ::std::to_addressextracts raw pointers from iterators.- Out‑of‑bounds pointer arithmetic is undefined behavior.