Contents
Arrays
Arrays in C++
In C++, an array is a collection of elements of the same data type, stored in contiguous memory locations. It allows you to store multiple values in a single variable and access them using an index. The size of the array must be specified at the time of declaration, and it cannot be changed later
Declaring and Initializing Arrays
Here’s how to declare and initialize arrays in C++:
1. Single-dimensional Array: This is the simplest form of an array.
Example:
#include
using namespace std;
int main() {
// Declare and initialize a single-dimensional array
int numbers[5] = {1, 2, 3, 4, 5};
// Access and print array elements
for (int i = 0; i < 5; i++) {
cout << "Element at index " << i << ": " << numbers[i] << endl;
}
return 0;
}
Output:
Element at index 0: 1
Element at index 1: 2
Element at index 2: 3
Element at index 3: 4
Element at index 4: 5
2. Multi-dimensional Array: Arrays can have more than one dimension. A two-dimensional array is commonly used to represent matrices.
#include
using namespace std;
int main() {
// Declare and initialize a two-dimensional array
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// Access and print array elements
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << "Element at [" << i << "][" << j << "]: " << matrix[i][j] << endl;
}
}
return 0;
}
Output:
Element at [0][0]: 1
Element at [0][1]: 2
Element at [0][2]: 3
Element at [1][0]: 4
Element at [1][1]: 5
Element at [1][2]: 6
Important Points about Arrays in C++:
- Indexing: Array indexing starts from 0. The first element is accessed using index 0, the second with index 1, and so on.
- Size Limitation: The size of the array must be a constant expression and cannot be modified after declaration.
- Memory Management: The size of the array affects memory usage. For large data sets, dynamic arrays (using
new
keyword) orstd::vector
from the STL (Standard Template Library) can be used for flexibility.
Dynamic Arrays
If you need to create an array whose size can be determined at runtime, you can use dynamic memory allocation.
Example:
#include
using namespace std;
int main() {
int size;
cout << "Enter the size of the array: ";
cin >> size;
// Dynamically allocate an array
int* dynamicArray = new int[size];
// Initialize array elements
for (int i = 0; i < size; i++) {
dynamicArray[i] = i * 2; // Assigning values
}
// Print the array elements
for (int i = 0; i < size; i++) {
cout << "Element at index " << i << ": " << dynamicArray[i] << endl;
}
// Free the allocated memory
delete[] dynamicArray;
return 0;
}
Output:
Enter the size of the array: 5
Element at index 0: 0
Element at index 1: 2
Element at index 2: 4
Element at index 3: 6
Element at index 4: 8
But we can have array of void pointers and function pointers. The below program works fine.
int main()
{
void *arr[200];
}
How to print size of array parameter in C++?
In C++, calculating the size of an array can be misleading when done within functions. Here’s an example that illustrates this issue.
// A C++ program demonstrating the incorrect method
// of computing the size of an array passed to a function
#include
using namespace std;
void checkSize(int arr[])
{
cout << sizeof(arr) << endl;
}
int main()
{
int a[10];
cout << sizeof(a) << " ";
checkSize(a);
return 0;
}
Output:
40 8
Time Complexity: O(1)
Auxiliary Space: O(n) (where n is the array size)
In the output, the first cout
statement in main()
displays 40
, while the second in checkSize()
shows 8
. The difference arises because arrays are passed as pointers to functions. Thus, both checkSize(int arr[])
and checkSize(int *arr)
are equivalent. The output inside checkSize()
reflects the size of a pointer, not the array.
// A C++ program demonstrating how to use a reference
// to find the size of an array
#include
using namespace std;
void checkSize(int (&arr)[10])
{
cout << sizeof(arr) << endl;
}
int main()
{
int a[10];
cout << sizeof(a) << " ";
checkSize(a);
return 0;
}
Output:
40 40
Time Complexity: O(1)
Space Complexity: O(n) (where n is the array size)
Making a Generic Function
Example:
// A C++ program to demonstrate how to use templates
// and references to find the size of an array of any type
#include
using namespace std;
template
void checkSize(T (&arr)[n])
{
cout << sizeof(T) * n << endl;
}
int main()
{
int a[10];
cout << sizeof(a) << " ";
checkSize(a);
float f[20];
cout << sizeof(f) << " ";
checkSize(f);
return 0;
}
Output:
40 40
80 80
Time Complexity: O(1)
Space Complexity: O(n) (where n is the array size)
Determining the Size of a Dynamically Allocated Array
The next step involves printing the size of a dynamically allocated array. Here’s a hint to get you started:
#include
#include
using namespace std;
int main()
{
int *arr = (int*)malloc(sizeof(int) * 20);
// Note: You need to keep track of the size since sizeof will not work here
return 0;
}
In this case, since malloc
returns a pointer, you cannot directly determine the size of the allocated memory using sizeof
.
What is Array Decay in C++?
Array decay refers to the loss of both type and dimensions of an array, which typically occurs when an array is passed to a function by value or pointer. In this process, the first address of the array is sent, treating it as a pointer. As a result, the size reported is that of the pointer, not the actual size of the array in memory.
// C++ code to demonstrate array decay
#include
using namespace std;
// Function demonstrating Array Decay
// by passing array as a pointer
void demonstrateArrayDecay(int* p)
{
// Displaying the size of the pointer
cout << "Size of the array when passed by value: ";
cout << sizeof(p) << endl;
}
int main()
{
int a[7] = {1, 2, 3, 4, 5, 6, 7};
// Displaying the original size of the array
cout << "Actual size of array is: ";
cout << sizeof(a) << endl;
// Passing the array to the function
demonstrateArrayDecay(a);
return 0;
}
Output:
Actual size of array is: 28
Size of the array when passed by value: 8
How to Prevent Array Decay?
One common approach to address array decay is to pass the size of the array as a separate parameter and to avoid using sizeof
with array parameters. Another effective method is to pass the array by reference, which prevents the conversion of the array into a pointer and thus avoids decay.
// C++ code to demonstrate prevention of array decay
#include
using namespace std;
// Function that prevents array decay
// by passing the array by reference
void preventArrayDecay(int (&p)[7])
{
// Displaying the size of the array
cout << "Size of the array when passed by reference: ";
cout << sizeof(p) << endl;
}
int main()
{
int a[7] = {1, 2, 3, 4, 5, 6, 7};
// Displaying the original size of the array
cout << "Actual size of array is: ";
cout << sizeof(a) << endl;
// Calling the function by reference
preventArrayDecay(a);
return 0;
}
Output:
Actual size of array is: 28
Size of the array when passed by reference: 28
Preserving array size by passing a pointer to the array:
Another way to maintain the size is by passing a pointer to the array, which includes an extra dimension compared to the original array.
#include
using namespace std;
// Function to demonstrate Array Decay with a pointer
void pDecay(int (*p)[7]) {
// Display the size of the pointer to the array
cout << "Size of array when passing a pointer: ";
cout << sizeof(p) << endl;
}
int main() {
int a[7] = {1, 2, 3, 4, 5, 6, 7};
// Display original size of the array
cout << "Original size of array: ";
cout << sizeof(a) << endl;
// Passing a pointer to the array
pDecay(&a);
return 0;
}
Output:
Original size of array: 28
Size of array when passing a pointer: 8