How can I output something when out of memory?
I have a custom set of malloc[, realloc and calloc] and free functions. For now the project just uses them as a wrapper for the normal versions of the functions. These wrapper functions terminate the program and should give an output to indicate the error.
At the moment the function to output the error message looks like this:
#ifdef __linux__
void memory_error() {
if (errno == ENOMEM)
printf("%s\n", "Out of memory or memory is limited. Fatal error. The program needs to terminate.");
else
printf("%s\n", "Memory allocation failed. Fatal error. The program needs to terminate.");
}
#else
void memory_error() {
printf("%s\n", "Memory allocation failed, likely due to being out of "
"memory or memory being limited for this program. "
"Fatal error. The program needs to terminate.");
}
#endif
The problem is that printf()
sometimes allocates memory and if I am out of memory, that will fail. Does fwrite()
allocate memory? And if so, is there a portable (so no write system call) option to output something without having to allocate more memory?
So far as a working solution for unix systems I could do this:
#ifdef __unix__
#define write_str_no_alloc(str) write(STDERR_FILENO, str, sizeof(str))
#else
#define write_str_no_alloc(str) ???
#endif
I am missing a solution for windows. I would prefer a general solution for both, but this would work for me.
On POSIX systems the write
function directly invokes the write
system call, so no memory allocation happens there.
Windows has a _write
function which is part of its POSIX compatibility layer, and is also documented to invoke the OS directly without buffering:
These functions invoke the operating system directly for lower-level operation than that provided by stream I/O. Low-level input and output calls don't buffer or format data.
So you can do this:
#ifdef _MSC_VER
#include <io.h>
#define write_str_no_alloc(str) _write(2, str, sizeof(str))
#else
#define write_str_no_alloc(str) write(STDERR_FILENO, str, sizeof(str))
#endif
Note that this requires the argument to be a string literal or an array, otherwise sizeof
won't give the desired result.