It's true that even with reasonable allocation failure reporting on a non-overcommit system, you can use too much memory and make life unpleasant for users without actually seeing allocations fail. Bounding resource use is important regardless. That's an issue of good behavior, however. Even absent good behavior, programs should at least be robust.
One of the reasons overcommit bothers me so much is that infects programming communities with the idea that resource consumption doesn't matter, since if you use too much, you're just going to get a SIGKILL anyway.
Unwind the stack and present an error message or take other appropriate action, just as we would for any other error. By unwinding the stack, we release owned resources, and some of those resources happen to be memory blocks. What makes memory so special?
> just finding all of your allocations is a nightmare in and of itself
Huh? In a non-GC system, if you can't find your allocations, you're leaking memory.
Memory is special insofar as it is a core resource that has so much contention that OOM situations may not be directly because of your application, and recovery may not even be possible without allocation.
I'm slowly coming to realize my argumentative point is losing ground -- this is great! :-)
The problem I'm talking about is allocation failure and OOM are not the same: handling out-of-memory reliably is a lot more than just checking for NULL in `malloc`, as I demonstrated. There's no guarantee that allocations will fail when they "should" and so you'll only learn that you're beyond reasonable limits when you touch enough pages that the operating system starts killing programs (possibly yours, possibly others), or when the user cannot actually use their computer in any reasonable manner.
> Windows is a very modern operating system and does not overcommit
Yeah definitely, it's why I was sure to mention the problems with swapping (sure, the memory is allocated and usable by the program, but in slow motion; not so great if you actually want to use the computer).
> The resource you're allocating is address space. When you run out of this resource, your allocations will fail. On overcommit systems, you don't allocate commit charge until you access the memory.
Yes, running out of virtual memory is one way for allocations to fail, but, as you say, there's a variety of different systems at play here. Only failure in one of those systems (requesting virtual memory/address space) is handled by checking for `malloc` returning NULL, and so focusing on just that is missing the forest for the trees. Presumably the overall goal is to handle memory exhaustion gracefully, not to check the return value of NULL (which is just one part of the former).