When the program ends, all memory (freed or not) is reclaimed by the operating system. It is still good practice to free everything you allocate, though - mainly just to be in the habit of it, or in case you extend your program so that it doesn't end where it used to.
When your program ends all of the memory will be freed by the operating system.
The reason you should free it yourself is that memory is a finite resource within your running program. Sure in very short running simple programs, failing to free memory won't have a noticable effect. However on long running programs, failing to free memory means you will be consuming a finite resource without replenishing it. Eventually it will run out and your program will rudely crash. This is why you must free memory.
On a desktop OS like Windows, Linux or MacOS, your memory will be cleaned up for you.
On some real-time or embedded operating systems, it won't be cleaned up for you.
But it's a good idea to always free memory when you've finished with it - bear in mind that while your program is running, all that memory is still in use. If you don't free it, the memory usage of the machine will increase.
You have to be careful about refactoring as well - say you start off writing a main()
function that allocates some memory, and you don't bother freeing it because the OS will do it for you. But then you move that code into a function that gets called lots of times, over a long period of time - suddenly you have a huge memory leak.
The memory is freed by the OS at program termination, but if all you have is a minor memory leak, that is the least of your worries.
More problematic is: 1) if it happens in a loop, your program balloons in size, and 2) in C++, if your "new"ed objects aren't "delete"d, your destructors aren't run, and this can lead to much more serious problems (mutex leaking, or leaking of resources NOT cleaned up by the OS, data integrity issues, the list goes on)
It is important to free memory properly so that tools that help you find memory leaks will have meaningful output when and if you need to track down issues. Allowing the OS to free the memory for you will add additional noise to any analytical tools that you may use later on. Even if the OS returns the memory to the system you should have a rock solid design that uses memory in a proper way and allows you the best use of tools.