On most operating systems targeted at hardware with an MMU (such as x86), the only way to actually get an error for a memory read is if the application address is unmapped. Since the MMU doesn't have an entry that tells it where to find in physical memory the data associated with the logical address the application asked for, it causes an interrupt and the operating system takes over, to do something about it.
But most operating systems don't do much to manage memory on behalf of the application, except to give it a contiguous chunk of memory of the desired size. The operating system doesn't allow the applications to muck about in the MMU, either, since most MMU's aren't quite smart enough to let applications do things safely without affecting other programs negatively (either by accident or malice).
So when you malloc()
something, if your app doesn't already have a place to put that in its existing address space, it asks the operating system for more, but when you later free()
it, unless that happens to be at the very end of the address space for your app, you can't give it back to the operating system to make that memory area cause an error when you try to read it.
There are some ways to get that, for instance, with mmap()
, but that's not really the right reason to use that function.