Elephant Parade, Part 3: Dynamically Allocated Arrays
Meh. We still haven't solved the problem.
Which problem is that?
Five
Elephant
s still isn't a parade!Well, we can make the maximum bigger now, if we want.
There shouldn't be a maximum! The user should be able to have as long a parade as they want!
You're right. Let's try a different approach.
Dynamically Allocated Arrays
We've talked about statically sized arrays on the stack. Statically sized means that we know the size of the array at compile time.
We need to know the size of arrays on the stack, because the entire array is contained within the stack frame.
The compiler needs to be able to figure out how big the stack frame is for each function so that the right amount of memory is allocated when the function is called.
But we don't have that problem on the heap! Heap memory is allocated whenever we want. The compiler doesn't have to know beforehand how much to allocate. Whenever we want heap memory, however much we want, we just ask for it.
Key Point: When you allocate an array on the heap, you can use a non-constexpr
variable as the array size!
For example, if you want to get the array size from the user, you can't say;
size_t numElements;
cin >> numElements;
int arr[numElements]; // ERROR! numElements is not a compile-time constant!
but this version will work:
size_t numElements;
cin >> numElements;
int* arr = new int[numElements];
Key ideas:
- You can allocate an array on the heap using
new...[]
. - The address that is returned is the address of the first element of the array.
- So you can use indexing notation as usual.
- The array isn't placed inside our stack frame, so the size of the array can be given by a variable!
As Many Elephants As You Want
Now we can choose the size of an array based on what happens during execution.
So we can make the array as big as the user wants!
Here's a new version of the Elephant Parade example code. We've changed it so that it
- Asks the user for the number of
Elephant
s at the beginning. - Allocates an array of the given number of
Elephant
objects (not pointers).- We've left this part blank for now.
- Prompts the user for information about each
Elephant
.
int main() {
size_t numElephants;
cout << "How many elephants will parade? ";
cin >> numElephants;
////////////////////////////////////////////////////
// Allocate an array of numElephants Elephant objects
////////////////////////////////////////////////////
for (size_t i = 0; i < numElephants; ++i) {
cout << "Please enter elephant " << i << endl;
string name;
cout << "Name: ";
cin >> name;
int age;
cout << "Age: ";
cin >> age;
Elephant el{name, age};
elephants[i] = el;
}
// We'll just assume this works
sortElephantsByName(elephants, elephants + numElephants);
cout << "The elephants are parading!" << endl;
for (size_t i = 0; i < numElephants; ++i) {
cout << elephants[i].getName() << " (" << elephants[i].getAge() << ")" << endl;
}
return 0;
}
Answer:
Elephant* elephants = new Elephant[numElephants];
Let's quickly walk through this version to see what it looks like in memory.
(When logged in, completion status appears here.)