Arrays
An array is a fixed-size collection of elements of the same type, stored contiguously in memory. C++ inherits its array type directly from C, which makes it fast and simple — but also unforgiving. Unlike higher-level languages, C++ arrays do not know their own size at runtime and do not check whether an index is in range.
Declaring and initializing arrays
An array declaration specifies the element type, a name, and the number of elements in square brackets. Indexing is zero-based, so an array of size 5 has valid indices 0 through 4.
arrays_basics.cpp
#include <iostream>
int main() {
int arr[5]; // uninitialized — holds garbage values
int scores[5] = {90, 85, 77, 60, 100}; // fully initialized
int zeros[5] = {}; // all elements zero-initialized
int partial[5] = {1, 2}; // {1, 2, 0, 0, 0}
int inferred[] = {10, 20, 30}; // size deduced as 3
for (int i = 0; i < 5; i++) {
std::cout << scores[i] << " ";
}
std::cout << std::endl;
return 0;
}Arrays decay to pointers in functions
When you pass an array to a function, it does not copy the array. Instead, the array “decays” into a pointer to its first element. This means the function has no way to know how many elements the array actually has — the size information is lost.
array_decay.cpp
#include <iostream>
void printSize(int arr[]) {
// arr is really just an int*, NOT the original array type.
std::cout << "Inside function: " << sizeof(arr) << " bytes" << std::endl;
}
int main() {
int numbers[10] = {0};
std::cout << "In main: " << sizeof(numbers) << " bytes" << std::endl;
printSize(numbers);
return 0;
}Out-of-bounds access is undefined behavior
C++ does not check array bounds at compile time or at runtime. Reading or writing past the end of an array does not throw an exception — it simply accesses whatever memory happens to sit there, which may belong to another variable entirely.
out_of_bounds.cpp
int arr[3] = {1, 2, 3};
arr[5] = 99; // undefined behavior: writes past the array's memory
int x = arr[10]; // undefined behavior: reads garbage, or crashesstd::array — the safer modern alternative
std_array.cpp
#include <array>
#include <iostream>
void printAll(const std::array<int, 5>& arr) {
// arr.size() still works correctly here — no decay!
for (std::size_t i = 0; i < arr.size(); i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
int main() {
std::array<int, 5> scores = {90, 85, 77, 60, 100};
std::cout << "Size: " << scores.size() << std::endl;
printAll(scores);
// .at() performs bounds checking and throws std::out_of_range
try {
std::cout << scores.at(10) << std::endl;
} catch (const std::out_of_range& e) {
std::cout << "Caught: " << e.what() << std::endl;
}
return 0;
}Feature | C-style array | std::array |
|---|---|---|
Size known at runtime | No (decays to pointer) | Yes (.size()) |
Bounds checking | Never | Only with .at() |
Works with algorithms | Partially | Fully |
Header required | None (built-in) | <array> |
Recommended for new code | Avoid when possible | Yes |