C++ Arrays
A basic data structure in C++, arrays are used to hold a sequential collection of elements of the same type that have a fixed size. Instead of declaring separate variables for each value, they let you store numerous values as a single unit.
Defining Arrays
Like any other variable, an array needs to be explicitly declared before it can be used. Its name, element types, and the quantity of elements it will contain are all specified in this declaration. With the initial element at the lowest address and the last member at the highest, the elements of an array are kept in memory in a continuous fashion.
Syntax for declaring a single-dimension array:
type arrayName[arraySize];
- type: Each element’s type, such as int, double, or char, is the array’s base type.
- arrayName: The array variable’s name that you give it.
- arraySize (dimension): How many items the array can contain. This size needs to be expressed as an integral constant that is larger than zero. This implies that at compilation time, the size of any built-in arrays defined on the stack must be known. A built-in array’s size cannot be declared via user input.
Example: For instance, to declare a 10-element array of type double called balance
double balance[15]; // Declares an array of 10 double values
To initialize the components of an array called squares, which consists of four integers:
int squares[19]; // declares an array of 4 integers
for (int i = 0; i < 4; ++i)
{
squares[i] = i * i; // initializes elements
}
To avoid specifying the array size twice, you can control it with a constexpr constant.
constexpr int sq_size = 4; // Use a constant expression for the size [20]
int squares[sq_size]; // array declaration with constant size [20]
for (int i = 0; i < sq_size; ++i)
{
squares[i] = i * i;
}
Initializing Arrays
To prevent unexpected outcomes, array members should be initialized before being utilized.
Arrays can be initialized in a number of ways:
- After proclamation, one by one:
- The values are contained in curly braces and separated by commas at the time of declaration using an initialisation list {}.
- Ignoring array size at initialization: You don’t always need to specify an array’s length if you initialize it when you define it. Depending on how many initial values are supplied, the compiler will calculate the size.
Important considerations for initialization:
- Any remaining members are set to zero if the explicit array length exceeds the number of beginning values.
- The excess values are either ignored or an error is indicated if there are more beginning values than the array length.
- A string literal can be used to do a shorthand initialization for C-style character strings:
Accessing Array Elements
Indexes, or subscripts, are used to access array elements. Zero-indexed C++ arrays have a 0 first element. A ten-element array can have indices 0–9.
To access array elements, use the subscript operator [].
Example: For instance, balance = 12.23; gives the element at index 3 (the fourth entry in the balance array) the value 12.23.
Code example demonstrating access and modification:
#include <iostream>
#include <iomanip> // For std::setw
using namespace std;
int main ()
{
int n[ 10 ]; // n is an array of 10 integers
// Initialize elements of array n to values (e.g., i + 100)
for ( int i = 0; i < 10; i++ )
{
n[ i ] = i + 100; // Set element at location i to i + 100
}
// Outputting values
cout << "Element" << setw( 13 ) << "Value" << endl;
for ( int i = 0; i < 10; i++ )
{
cout << setw( 7 ) << i << setw( 13 ) << n[ i ] << endl; // Accessing elements
}
return 0;
}
Examples
Element Value
0 100
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
Type size_t, an unsigned type defined in the header that is guaranteed to be large enough to hold the size of any object in memory, is typically defined when a variable is used to subscript an array.
Inability to check boundaries is a key feature of C++ built-in arrays. This means that the compiler won’t raise an error if you access an index outside the array’s defined range (for example, arr for an array with elements from arr to arr), but it may cause unexpected behaviour, memory errors, or more serious programming errors like buffer overflows. It is your duty as the programmer to make that array accesses remain within the allowed parameters.
You can also read What Is Mean By Functions In C++ With Examples?
Arrays and Pointers
In C++, arrays and pointers are closely related. Without an index, an array’s name is interpreted as a constant pointer to its first entry. This characteristic enables array navigation using pointer arithmetic.
Example using pointer notation to access array elements:
#include <iostream>
int main() {
int intArray[] = { 31, 54, 77, 52, 93 }; // array declaration
// Using pointer arithmetic to print values
for (int j = 0; j < 5; j++) {
std::cout << *(intArray + j) << std::endl; // print value by dereferencing pointer arithmetic
}
return 0;
}
Output
31
54
77
52
93
An array’s memory address a pointer to its first element is supplied as a parameter to a function instead of the array itself being copied. This indicates that the calling application and the function both access the same array.
Multidimensional Arrays
Multidimensional arrays are supported in C++. Another set of square brackets is used to add another dimension. Like a spreadsheet table, a two-dimensional array can be represented as rows and columns.
An example of a declaration int four_by_three; (a two-dimensional array with 12 integers arranged in four rows of three columns) int two; (an array of two integers)
For each dimension, an index must be specified in order to access elements. For instance, d can be used to retrieve a two-dimensional array element. d.
Initialization of multidimensional arrays: Multidimensional arrays can be initialised with nested braces.
int arr[23][24] = { {5, 0, 0}, {7, 0, 0} }; //
int arr[][24] = { {5}, {7} }; // You can omit the size of the first dimension
The compiler determines the first dimension’s size from the initializers if you leave it blank. The remaining items are set to zero if you supply fewer initializers than the size of the array.
Class Arrays / Arrays of Objects
An array is referred to as a class array if any of its elements are objects of a class type. An object array can be declared and used using the same syntax as other array types.
Each array element automatically invokes the default constructor when the declaration is made without explicit initialization.
Example of an array of objects:
#include <iostream>
class cl {
int i;
public:
// Default constructor (called for uninitialized arrays of objects)
cl() { i = 0; std::cout << "Default constructor invoked" << std::endl; }
// Parameterized constructor (called for initialized arrays of objects)
cl(int j) { i = j; std::cout << "Parameterized constructor invoked with " << j << std::endl; }
void set_i(int j) { i = j; }
int get_i() { return i; }
};
int main() {
// Declaring an array of objects.
// Default constructor is called for each element.
cl obArray[24]; // [118]
std::cout << "\nInitialized array elements directly:\n";
cl initializedArray[24] = {10, 20, 30}; // Parameterized constructor called for each element
// Accessing and modifying members of objects within the array
for(int i = 0; i < 3; i++) {
obArray[i].set_i(i + 1); // Accessing and modifying using . operator
}
// Displaying values
std::cout << "\nValues in obArray:\n";
for(int i = 0; i < 3; i++) {
std::cout << "obArray[" << i << "]: " << obArray[i].get_i() << "\n";
}
std::cout << "\nValues in initializedArray:\n";
for(int i = 0; i < 3; i++) {
std::cout << "initializedArray[" << i << "]: " << initializedArray[i].get_i() << "\n";
}
return 0;
}
Output
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Initialized array elements directly:
Parameterized constructor invoked with 10
Parameterized constructor invoked with 20
Parameterized constructor invoked with 30
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Default constructor invoked
Values in obArray:
obArray[0]: 1
obArray[1]: 2
obArray[2]: 3
Values in initializedArray:
initializedArray[0]: 10
initializedArray[1]: 20
initializedArray[2]: 30
Dynamic Allocation of Arrays of Objects: The new[] operator allows you to dynamically allocate arrays of objects. This makes it possible for arrays to have their size decided at runtime.
#include <iostream>
#include <string> // For std::string
class MyClass {
public:
MyClass() {
std::cout << "MyClass default constructor called" << std::endl;
}
MyClass(const std::string& msg) : message(msg) {
std::cout << "MyClass parameterized constructor called with: " << message << std::endl;
}
~MyClass() {
std::cout << "MyClass destructor called" << std::endl;
}
std::string message = "Default";
};
int main() {
int numObjects;
std::cout << "Enter number of objects to allocate dynamically: ";
std::cin >> numObjects;
// Dynamically allocate an array of MyClass objects using new[]
// Default constructor is called for each element
MyClass* objArray1 = new MyClass[numObjects];
std::cout << "\nInitializing with brace list (C++11 and later):\n";
// For C++11 and later, you can use a braced list for initialization
// If fewer initializers than size, remaining elements are value-initialized
MyClass* objArray2 = new MyClass[126]{MyClass("One"), MyClass("Two")};
// Access elements using the correct arrow operator (->) for pointers
// This explicitly accesses the first element of the array
objArray1[0].message = "First dynamic object"; // Or objArray1->message
std::cout << "Message for objArray1[0]: " << objArray1[0].message << std::endl; // Or objArray1->message
// objArray2 is also a pointer, so we access its elements with array indexing
// The first element
std::cout << "Message for objArray2[0]: " << objArray2[0].message << std::endl; // Or objArray2->message
// A later element that was default-constructed
std::cout << "Message for objArray2[23]: " << objArray2[23].message << std::endl; // Will be default constructed
// Deallocate arrays using delete[]
delete[] objArray1; // Important to use delete[] for arrays
delete[] objArray2;
return 0;
}
Output
Enter number of objects to allocate dynamically: 23
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
Initializing with brace list (C++11 and later):
MyClass parameterized constructor called with: One
MyClass parameterized constructor called with: Two
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
MyClass default constructor called
Message for objArray1[0]: First dynamic object
Message for objArray2[0]: One
Message for objArray2[23]: Default
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
MyClass destructor called
You must use delete[] to deallocate memory that has been allocated for an array using new[]. Memory leaks could result from using delete alone (without the brackets), which would only release the memory of the first element.
Standard Library Arrays ( and )
Strong container classes from the C++ Standard Library provide safer substitutes for the rudimentary built-in arrays as well as higher-level abstractions. It is generally advised to utilise them instead of built-in arrays. Std::array and std::vector are two of the many helpful container classes found in the Standard Template Library (STL), which is a component of the C++ Standard Library. Since both are templates, they can contain bespoke or pre-installed types.
Std::array:
- Defined in the header .
- Enables the creation of arrays on the stack with fixed sizes.
- They must be known at build time and provided as a template parameter since, in contrast to built-in arrays, they cannot be made smaller or larger at runtime.
- Benefits: Eliminates problems like passing them as “dumb pointers” by providing compile-time size checks. They enable ranged for loops by implementing the begin() and end() procedures. Unlike built-in arrays, they additionally offer copy and assignment operations.
- Std::array offers an at() function for bounds-checked access that checks the range and raises an out_of_range exception if the index is wrong.
Std::vector:
- This class is an array that is dynamically allocated.
- It automatically controls storage allocation and defines variable-size collections, growing and shrinking in response to data additions or deletions.
- It enables random access via the [] operator, just like std::array.
- When the precise number of elements is unknown at compile time and could change during runtime, it ought to be utilised.
Drawbacks of Built-in Arrays
Despite being essential, built-in arrays have a number of drawbacks:
Fixed Size: Their size cannot be altered after creation and must be known at compile time. Once the array is established, elements cannot be added or removed.
No Bounds Checking: Built-in arrays in C and C++ don’t automatically check for boundaries. In addition to causing undefined behaviour, accessing an index outside of the declared range might result in major issues like buffer overflows.
No Copy or Assignment: There is no support for direct copy or assignment operations using = in built-in array types. Elements must be manually copied, frequently repeatedly.
Decay to Pointers: A pointer to the array’s first element is frequently implicitly converted (decayed) by the array name. Although helpful for some activities, such as passing to functions, this can lead to frequent mistakes and misunderstandings.
Not Standard Library Container Compatible: Built-in arrays do not behave exactly like standard containers and cannot be used directly as the value type of a normal container.
Memory Fragmentation: It can be difficult to locate a contiguous block of memory big enough to handle very large arrays, and memory defragmentation may occasionally be necessary.
You can also read What Are The Jump statements In C++ With Code Examples?