WEBVTT

00:00:00.640 --> 00:00:02.480
Now let's get back to arrays.

00:00:02.480 --> 00:00:04.580
In one of the previous lessons,

00:00:04.590 --> 00:00:07.280
I took a little bit of time to explain why the size of an

00:00:07.280 --> 00:00:09.640
array needs to be known at compile time.

00:00:09.640 --> 00:00:12.770
Since that's just how static arrays work,

00:00:12.770 --> 00:00:16.700
the compiler needs to know how big the array is going to be so that it

00:00:16.700 --> 00:00:20.050
knows how to manage stack memory and optimize it.

00:00:20.440 --> 00:00:22.120
But this is very limiting.

00:00:22.130 --> 00:00:25.860
What if I want to let the user specify the size of the array?

00:00:26.240 --> 00:00:28.080
I created an integer variable,

00:00:28.080 --> 00:00:31.150
which will be initialized by the input from the terminal,

00:00:31.160 --> 00:00:35.150
and then I will use that variable to set the size of the array.

00:00:36.040 --> 00:00:37.060
Let's compile this.

00:00:38.540 --> 00:00:41.960
I need to specify the size, so let's say 5.

00:00:43.140 --> 00:00:45.360
And it seems that this worked.

00:00:45.370 --> 00:00:46.810
No errors or warnings.

00:00:46.810 --> 00:00:52.460
So why did I have that conspiracy theory about knowing the size at compile time?

00:00:52.840 --> 00:00:58.060
Unfortunately, sometimes this will work, depending on which compiler you use.

00:00:58.640 --> 00:01:02.230
This feature of declaring the array size from a variable

00:01:02.240 --> 00:01:06.950
is known as variable length arrays, or VLA for short.

00:01:07.840 --> 00:01:12.250
C++ does not support VLAs in its language standard.

00:01:12.640 --> 00:01:15.600
The reason that this worked for me is because my new

00:01:15.600 --> 00:01:19.090
compiler has an extension for compiling C code,

00:01:19.100 --> 00:01:24.190
and C version 99 does have a support for variable length arrays.

00:01:24.190 --> 00:01:27.310
But you shouldn't rely on this feature because it

00:01:27.310 --> 00:01:29.320
will not work with all compilers,

00:01:29.330 --> 00:01:34.860
and using non‑standard C++ code will affect the portability of your programs.

00:01:35.340 --> 00:01:38.940
I will add this special flag to the command to let the compiler

00:01:38.940 --> 00:01:41.830
know that it should treat VLAs as an error.

00:01:41.830 --> 00:01:48.330
And now if I try to compile this, array declaration will result in an error,

00:01:48.460 --> 00:01:52.060
as it should, because we don't want them in C++.

00:01:52.440 --> 00:01:57.060
If we want to create arrays with dynamic size, we can allocate them on the heap.

00:01:57.440 --> 00:02:00.160
Let's do that in our calculator program.

00:02:00.740 --> 00:02:05.700
I will remove this SIZE constant and create a non‑constant size variable,

00:02:05.710 --> 00:02:07.960
which will store the input from the user.

00:02:08.840 --> 00:02:12.260
We will need another message to ask the user about the number of

00:02:12.260 --> 00:02:15.260
operands and receive the input as a response,

00:02:16.240 --> 00:02:21.160
and change this size to lowercase because we don't use the constant anymore.

00:02:21.540 --> 00:02:24.260
I just want to mention that one possible solution is

00:02:24.260 --> 00:02:26.240
to make this array really large.

00:02:26.250 --> 00:02:30.060
For example, we can make it store 100 elements.

00:02:30.440 --> 00:02:33.910
That way, we will have a static array with a lot of space,

00:02:33.910 --> 00:02:37.090
and we can only use the number of elements that we

00:02:37.090 --> 00:02:39.350
actually need to store the operands.

00:02:39.740 --> 00:02:44.600
This would work, but in real projects this is a really big waste of space,

00:02:44.610 --> 00:02:48.350
especially if we know that we're not going to need so much elements.

00:02:48.740 --> 00:02:49.560
Instead,

00:02:49.570 --> 00:02:54.050
I want to only allocate the amount of space in memory that we actually need.

00:02:54.440 --> 00:02:57.370
There is a special version of the new operator that

00:02:57.370 --> 00:03:00.050
supports the creation of arrays on the heap.

00:03:00.940 --> 00:03:05.240
You specify the size of the array inside of the square brackets and

00:03:05.240 --> 00:03:08.050
put the data type of these elements next to it.

00:03:09.040 --> 00:03:11.460
This will allocate an array on the heap.

00:03:12.340 --> 00:03:14.980
Of course, since this is allocated on the heap,

00:03:14.990 --> 00:03:18.160
we need to store the memory address in some pointer.

00:03:18.540 --> 00:03:21.640
Now you can see why I said that using size of operator to

00:03:21.640 --> 00:03:24.150
determine the number of elements is bad.

00:03:24.540 --> 00:03:27.810
If you try to do that with this heap‑allocated array,

00:03:27.820 --> 00:03:31.430
it wouldn't work because this nums is just a pointer

00:03:31.430 --> 00:03:33.360
to a memory address on the heap.

00:03:33.740 --> 00:03:37.870
It makes sense that we are able to create dynamically sized arrays on the heap

00:03:37.880 --> 00:03:41.070
because heap provides us with dynamic memory allocation.

00:03:41.070 --> 00:03:46.360
It literally allocates memory at runtime and not at compile time.

00:03:46.740 --> 00:03:49.040
The rest of the code can still stay the same.

00:03:49.040 --> 00:03:53.850
We just need to replace this SIZE constant with size variable in a few places.

00:03:54.240 --> 00:03:58.750
Once we do that, everything else should work like it used to. However,

00:03:58.760 --> 00:04:01.270
if you paid attention in the previous module,

00:04:01.280 --> 00:04:04.850
you might be wondering if this would cause a memory leak.

00:04:05.740 --> 00:04:10.170
After all, we are allocating memory on the heap, but we are not releasing it.

00:04:10.170 --> 00:04:15.570
And you're right. We do need to release allocated memory, so I will use the

00:04:15.570 --> 00:04:18.350
delete operator at the end of the main function.

00:04:18.740 --> 00:04:21.829
One thing to note is that if you allocate an array on the

00:04:21.829 --> 00:04:24.960
heap with this new square brackets operator,

00:04:24.970 --> 00:04:29.450
you also need to deallocated with delete[] operator.

00:04:29.840 --> 00:04:32.980
This is because the delete needs to loop through the array and call

00:04:32.980 --> 00:04:36.230
the destructor of each object, if one is provided,

00:04:36.230 --> 00:04:36.860
of course.

00:04:37.840 --> 00:04:41.650
Okay, now let's compile this to see if the program still works.

00:04:42.440 --> 00:04:46.160
I am asked to provide the number of operands. I will choose 3.

00:04:47.140 --> 00:04:50.650
Let's pick some numbers and choose the plus operator.

00:04:51.740 --> 00:04:54.060
And yes, everything still works,

00:04:54.060 --> 00:04:57.990
but now the user can specify the number of operands, and no

00:04:57.990 --> 00:05:02.240
modifications of the code itself are required. So if you want to

00:05:02.240 --> 00:05:06.780
dynamically set the size of an array, use heap. This is actually a

00:05:06.780 --> 00:05:08.820
common use case for heap memory,

00:05:08.830 --> 00:05:13.010
especially in the old days when we didn't have all of those fancy classes

00:05:13.010 --> 00:05:16.760
from C++, but we will talk about these classes later.
