WEBVTT

00:00:00.640 --> 00:00:03.160
Let's sum up everything we covered in this module.

00:00:03.740 --> 00:00:07.160
Pointer variables encode object's location in memory.

00:00:07.360 --> 00:00:09.800
The memory address, which pointer contains,

00:00:09.810 --> 00:00:14.250
is just the location of the first byte that makes up an object; however,

00:00:14.250 --> 00:00:17.210
compilers should be aware of how many following bytes it

00:00:17.210 --> 00:00:19.580
needs to read to get the full object.

00:00:19.590 --> 00:00:22.440
This is why we assign data types to pointer variables.

00:00:22.440 --> 00:00:24.590
Based on the given data type,

00:00:24.600 --> 00:00:27.690
program will know how many bytes it needs to look up in memory

00:00:27.700 --> 00:00:30.460
when we decide to dereference a certain pointer.

00:00:31.440 --> 00:00:35.310
Pointer's data type does not influence the size of a pointer variable.

00:00:35.370 --> 00:00:38.790
Pointer size will always be consistent because it always needs

00:00:38.790 --> 00:00:41.410
to store a memory address and nothing else.

00:00:41.490 --> 00:00:45.870
For example, on 32‑bit systems, the pointer size will be 4 bytes,

00:00:45.880 --> 00:00:48.450
and on 64‑bit systems, 8 bytes.

00:00:49.940 --> 00:00:53.810
We can also declare a void pointer, which is a pointer without data type.

00:00:53.810 --> 00:00:58.000
You cannot dereference this pointer for obvious reasons,

00:00:58.010 --> 00:01:01.040
but the pointer can still hold an address for memory.

00:01:01.050 --> 00:01:02.960
This can be used as a placeholder,

00:01:02.970 --> 00:01:06.760
which we can later typecast into some other type of pointer.

00:01:08.540 --> 00:01:10.620
Every time you declare a local variable,

00:01:10.620 --> 00:01:12.960
that variable will be pushed onto the stack.

00:01:12.960 --> 00:01:17.040
Stack is a special region in memory controlled by the CPU.

00:01:17.040 --> 00:01:20.970
Basically, the processor will use something called a stack pointer,

00:01:20.970 --> 00:01:24.220
which always points to the next available piece of memory.

00:01:24.360 --> 00:01:29.060
Local variables are allocated next to each other; they are stacked together.

00:01:29.240 --> 00:01:32.020
This is a simplified look at how all of this works,

00:01:32.030 --> 00:01:35.660
but CPU will also have to keep track of stack frames because they wrap

00:01:35.660 --> 00:01:39.140
around all of the variables that belong to the same scope.

00:01:39.150 --> 00:01:41.210
Once the program reaches the end of the scope,

00:01:41.220 --> 00:01:43.590
CPU will just return the stack pointer,

00:01:43.600 --> 00:01:47.570
and all of the local variables from that scope will be removed from memory.

00:01:47.570 --> 00:01:52.620
Heap, also known as free store,

00:01:52.630 --> 00:01:55.130
is another important region of memory which we can

00:01:55.130 --> 00:01:57.780
use to allocate memory at runtime.

00:01:57.800 --> 00:02:00.910
New operator will allocate memory on the heap and return

00:02:00.910 --> 00:02:03.260
the memory address of that allocation.

00:02:04.240 --> 00:02:06.970
The size of the allocation will depend on the data

00:02:06.970 --> 00:02:08.669
type we provide to the operator.

00:02:08.669 --> 00:02:13.640
We need to store the returned memory address in a pointer; otherwise,

00:02:13.640 --> 00:02:16.460
we will not be able to access the allocated memory.

00:02:16.560 --> 00:02:18.980
Memory and heap is not managed by the scope,

00:02:18.980 --> 00:02:23.260
so we need to manually deallocate it with the delete operator.

00:02:23.440 --> 00:02:26.870
This operator needs the address of the allocated space on the heap,

00:02:26.880 --> 00:02:29.550
so make sure that you don't lose the pointer to it.

00:02:29.840 --> 00:02:30.820
If you don't do this,

00:02:30.820 --> 00:02:34.790
memory on the heap will stay allocated until the end of the whole program,

00:02:34.800 --> 00:02:36.560
which can cause a memory leak.

00:02:37.140 --> 00:02:38.620
Memory leaks are dangerous.

00:02:38.620 --> 00:02:41.740
If you don't deallocate memory, at some point,

00:02:41.750 --> 00:02:45.660
your program will probably crash because it will not be able to

00:02:45.660 --> 00:02:48.960
allocate any more memory to continue with the execution.

00:02:49.940 --> 00:02:52.220
Since stack memory is self‑managed,

00:02:52.230 --> 00:02:56.150
you should always use it unless you have a special reason to use heap.

00:02:56.150 --> 00:03:00.970
Stack has a predefined size, and it is usually small, around 2 MB.

00:03:01.040 --> 00:03:01.740
However,

00:03:01.740 --> 00:03:04.930
the allocation of memory on stack is really fast because it

00:03:04.930 --> 00:03:07.360
usually needs just one CPU instruction.

00:03:07.640 --> 00:03:08.630
On the other hand,

00:03:08.640 --> 00:03:11.220
your program will need to work with the operating system to

00:03:11.220 --> 00:03:13.250
find the available memory on the heap.

00:03:13.540 --> 00:03:16.340
The implementation of heap is not the same on every system,

00:03:16.340 --> 00:03:19.820
so the allocation time is usually slower and inconsistent.

00:03:19.830 --> 00:03:24.150
However, your programs might need more memory than the stack can offer.

00:03:24.160 --> 00:03:29.270
Another advantage of using heap is dynamic allocation of memory at runtime,

00:03:29.280 --> 00:03:32.160
which means that your programs can be more flexible.

00:03:32.340 --> 00:03:34.760
We'll talk more about that in the next module.

00:03:35.840 --> 00:03:40.070
New and delete operators don't just allocate and deallocate memory.

00:03:40.080 --> 00:03:44.630
They also execute the object's constructor and destructor respectively.

00:03:44.710 --> 00:03:47.120
This is why we should use them instead of legacy

00:03:47.120 --> 00:03:49.660
allocation functions like malloc and free.

00:03:50.640 --> 00:03:54.940
We can also overload these two operators to customize their allocation strategy.

00:03:54.940 --> 00:03:58.020
Instead of just allocating and deallocating memory,

00:03:58.020 --> 00:04:01.740
we can track the number of allocated bytes to prevent memory leaks,

00:04:01.750 --> 00:04:04.950
or we can use that data to create analytics.

00:04:05.140 --> 00:04:09.190
If you're working on an embedded system which does not provide heap by default,

00:04:09.200 --> 00:04:12.540
you can implement your own version of it by overloading new and delete.

00:04:12.540 --> 00:04:16.980
This will allow you to use all of the useful STL container classes which

00:04:16.980 --> 00:04:19.250
usually implement heap in the background.

00:04:20.339 --> 00:04:24.570
Now you know what heap memory is, why we need it, and how we can access

00:04:24.570 --> 00:04:29.220
it. Other than providing you with more memory to store large objects, heap

00:04:29.220 --> 00:04:33.870
also allows you to be flexible with allocating memory at runtime. This

00:04:33.870 --> 00:04:37.780
will become more apparent once we start to dynamically allocate arrays.

00:04:37.780 --> 00:04:42.300
Join me in the next module to learn more about arrays and their relation

00:04:42.300 --> 00:04:44.060
to heap and pointers.

00:04:44.150 --> 00:04:46.900
Thank you for watching, and if you have any questions,

00:04:46.900 --> 00:04:49.060
please ask them in the courses discussion.
