/* Demonstrate a way to test malloc() failtures by implementing a very minimal * version of malloc() that fails on command. * This will work for very simple programs that don't allocate much memory. * * Note that on some systems (notably Linux), malloc() will almost never fail. * If the computer is out of memory, malloc() succeeds anyway, in hopes that * the memory doesn't actually get used. If it is used, then the Linux kernel * has a variety of tricks to free up memory such as using swap space or * invoking the "out of memory" (OOM) killer. */ #include #include #include // Whether malloc should fail on command bool malloc_fail = false; // Statically allocate a chunk of memory; we'll hand out chunks of this on each // call to malloc() unsigned char reserved_memory[1024 * 1024]; // Keep track of where the next free byte of our memory is size_t next_free_idx = 0; // Our own version of malloc which void *malloc(size_t n_bytes) { // If we're failing on command if(malloc_fail){ return NULL; } // Or if we're genuinely out of memory if((sizeof reserved_memory) - next_free_idx < n_bytes){ return NULL; } // Otherwise, move the index by the allocated amount and return the pointer void* allocated_memory = reserved_memory + next_free_idx; next_free_idx += n_bytes; return allocated_memory; } // If we're going to implement malloc, we also need to implement free()! // We really ought to also implement calloc() and realloc(), but we'll be ok // as long as they're not used! // See https://www.gnu.org/software/libc/manual/html_node/Replacing-malloc.html void free(void *mem) { } int main(int argc, char* argv[]) { int* x = malloc(10); printf("Allocated x: 0x%lx\n", x); *x = 5; free(x); malloc_fail = true; int* y = malloc(10); printf("Allocated y: 0x%lx\n", y); //*y = 1; // This will crash! free(y); // Or we could just ask for a terabyte of memory int* z = malloc(1024 * 1024 * 1024 * 1024); printf("Allocated z: 0x%lx\n", z); free(z); printf("All done!\n"); }