7

I've been creating tests for a simple program that I created. I always check if the allocation of memory using malloc fails using something like this

int* ptr = malloc(sizeof(int) * x); if(!ptr){ //... exit(1); // but it could also not terminate abnormally and do something else } 

But usually, for my programs at least, malloc never fails, and those I can't really deterministically test the cases when malloc fails.

My question is: how can I test a program for the case of a memory allocation failure, if I've not control on the fact if malloc will fail or not? What should I do to test deterministically when malloc fails?

3
  • You can create your own malloc function and inject it with LD_PRELOAD. Commented Jun 25, 2016 at 0:34
  • nbro, What is your OS? Is it linux + glibc? Glibc's malloc has __malloc_hook pointer to redefine malloc: man7.org/linux/man-pages/man3/malloc_hook.3.html. You can redefine malloc to your own version which will fail according to some random variable or to some internal state (fail every 1000th call), and in most cases it will just call standard malloc. Alternatively you may define some ulimits on memory size and use standard malloc. Commented Jun 25, 2016 at 0:54
  • it is deprecated Commented Oct 7, 2020 at 7:17

3 Answers 3

6

Fake a malloc:

#define malloc(...) NULL int* ptr = malloc(sizeof(int) * x); 
Sign up to request clarification or add additional context in comments.

2 Comments

This seems to be a better solution with respect to what Douglas is suggesting... maybe I could even pass, say, the value of a directive at compile time or something similar, so that I don't have to add it manually to each .c whenever I want to test this failure of malloc? Any suggestions on how to do it, if possible (since I'm not that really expert in the preprocessor directives)?
Or #define malloc(s) my_alloc(s) The implement my_alloc(s) with calloc() and maybe rand() to fail at odd times.
5

When I needed to test memory allocation failures at different stages, I used a function xmalloc() like this:

static int fail_after = 0; static int num_allocs = 0; static void *xmalloc(size_t size) { if (fail_after > 0 && num_allocs++ >= fail_after) { fputs("Out of memory\n", stderr); return 0; } return malloc(size); } 

The test harness (part of the same source file) could set fail_after to any suitable value, and reset num_allocs to zero before each new test run.

int main(void) { int no1 = 5; for (fail_after = 0; fail_after < 33; fail_after++) { printf("Fail after: %d\n", fail_after); num_allocs = 0; test_allocation(no1); } printf("PID %d - waiting for some data to exit:", (int)getpid()); fflush(0); getchar(); return 0; } 

Then you can arrange to call xmalloc() in lieu of the 'real' malloc():

#define malloc(x) xmalloc(x) 

That would be placed after the definition of xmalloc() — though there are ways to work around that if need so be. You can tweak things all sorts of ways: limit the total size too, arrange to fail every Nth allocation, arrange to fail for N successive allocations after M successful ones, etc.

1 Comment

Detail: with your xmalloc(), return 0; is not a failure return when size==0.
4

You might want to call malloc with a negative value like this:

malloc(-1); 

This will make malloc return NULL and set errno to 12 ("Cannot allocate memory") accordingly.

To be honest this is not a "real" out-of-memory scenario, but i think for testing purposes this will do.

1 Comment

Perfect and reasonable! Compiler cusses: warning: argument 1 value ‘18446744073709551615’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=] What is it if not out-of-memory?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.