In the previous videos we saw how to allocate a piece of memory from the heap. We mentioned that, unlike stack memory, heap memory isn't automatically deallocated when we return from the function in which the allocation happened. Now we will talk about how to explicitly deallocate memory and will point out some common issues that can arise. Let's consider the function play_with_memory. It declares an integer i on the stack and then uses malloc to allocate space for an integer on the heap. pt is the integer pointer containing the address of the newly allocated space on the heap. Remember that memory for pt is located on the stack. Let's examine this code in the visualizer looking at the memory just before the function returns. We see that i is on the stack and its value is 15. pt is also on the stack and holds an address of memory on the heap. That location holds 49. When we return from the function the stack frame for play_with_memory is removed. Both i and pt are no longer allocated. But the integer on the heap (the one holding 49) remains. The problem is that we have no way to ever access this memory again. This memory has been given to us to use, so it won't be allocated again. However, we can't actually use it, because we don't have a pointer to it. This is called a *memory leak*. This leak doesn't cause a problem in our tiny program since the very next step is to return from main and terminate the program. However, memory leaks can be a serious problem. Suppose that you have a long-running program -- like a web browser -- that is calling play_with_memory in a loop. Let's simulate that. If we change our program to have 3 calls to play_with_memory and run it in the visualizer, you can see that just before main returns we have 3 integers allocated on the heap each with the value 49. Each call to play_with_memory leaks one more integer-sized piece of memory that can no longer be used. If this continues to occur, there will eventually be so much wasted memory that your program won't be able to allocate space for the variables it needs. Your program will encounter an out-of-memory error -- also known as ENOMEM. So how do you deallocate memory on the heap? free takes a single argument which is a pointer to the beginning of a block of memory that had been previously returned by a call to malloc. free returns that address to the system managing the memory for your program so that it can be reallocated for another purpose. Let's free the memory we allocated and then visualize our program again. pt points to the memory allocated with malloc, so passing it to free will deallocate it. The memory management system tracks the sizes of blocks that it allocated, so we don't have to tell free how much to deallocate. It will deallocate the entire block that was allocated in the malloc call that returned this address. Let's visualize our program. In the middle of the first play_with_memory we see that pt holds the address xxxxxx that holds 49. If we skip ahead to the second memory call we see that there is only one integer allocated on the heap -- the current one -- the integer from the previous call was freed correctly. Finally, when main is about to return, there is no memory left allocated on the heap. What would happen if we tried to dereference pt after the call to free? It might *appear* to work. pt still holds that same address on the heap and that memory is still there. free does NOT reset the value of pt and it doesn't itself change the values in the block of memory that is being free'd. It simply tells the memory management system that this block is now available for other purposes. So the address is still legal and if no other code has used that memory yet, then your program might seem fine. But as we've seen before, accessing memory that isn't allocated for your use is a mistake. Although it might appear to work in some cases, it isn't going to work in other cases where the memory has been reallocated. A pointer that points to memory that has already been freed is called a *dangling pointer* and is unsafe.