Is there any other way to know when the memory runs out that isn't making system calls and counting bytes? |
Even that is not possible in most cases (depending on your OS and runtime environment)
Usually, when you make a request for a memory block, the OS just says "OK" - what it really gives you is a set of page descriptors or something similar. When you access a page, it is actually reserved. But what, if no page can be given to you, due to insufficient memory? Depending on your OS you get some signal, or your program is terminated (however, there might be situations where not even terminate() is called).
So one idea could be to access memory upon reservation, i.e. combine a 'malloc' with an access to every allocated byte (it might well be that /some/ bytes can be reserved, but not all). Note that this doesn't apply to new (except the "just reserve" and "nothrow just reserve" variants), since it calls the constructor and thereby performs writing access to the reserved memory. But what do you gain from that? As stated above, the behavior is "strange", but most likely not a std::bad_alloc exception (doing it might, in some cases, be a Good Thing anyways, e.g. to avoid security risks or make debugging easier, since you see that the problem is out-of-memory related).
But let's not kid ourselves. What might be the situation in which you run out of memory on a modern system? Remind you, we aren't talking about plain RAM here - with the advent of virtual memory some 50 years ago the problem of "running out of memory" pretty much has been solved. Due to paging the memory needn't even bee continguous on the RAM/swap level (indeed cannot be, if parts of the RAM are swapped to disk). So we are talking about the situation that you have allocated a block that takes all available free (virtual and physical) memory, which is, on a modern system, 1 GB at least. Start counting the data you can fit in that.