0

I think I know but I don't want to continue my work being incorrect.

Most examples you see are...

char* temp;
char* temp1;

temp = malloc(10, sizeof(char);
temp1 = realloc(temp, 11*sizeof(char));

Now I am assuming that you don't use...

temp = realloc(temp, 11*sizeof(char));

Because if there is not enough memory you get a NULL ptr returned, thus leaving no way to access the original memory block.

So would the below be a good way to handle a NULL pointer being returned?

while((temp1 = realloc(temp, 11*sizeof(char))) == NULL)
    sleep(3);

temp = temp1;
temp1 = NULL;

I know some people say that when you put sleep in your code that there's probably a better way. But the way I see it, I have no choice but to wait.

JoeManiaci
  • 435
  • 3
  • 15
  • 3
    If `realloc()` returns `NULL`, then you have serious problems. And no, this is not only the reason why two pointers are necessary. If the memory block pointed to by the pointer is to be expanded, it is possible that it doesn't fit in its original place anymore, so `realloc()` will need to move it, changing the pointer (and invalidating it). –  Dec 09 '13 at 22:05
  • Is `sleep` supposed to give the OS a chance to move memory around? Anyway, I don't think I would rely on an *infinite loop*, as it may loop forever. – Jongware Dec 09 '13 at 22:05
  • Consider failing the operation or finding some unnecessary cache/data to flush instead. The sleep will do nothing to help a (single-threaded) application running out of address space as oppose to the whole system running out of virtual memory. – doynax Dec 09 '13 at 22:07
  • 1
    @Jongware - I will be working on systems with anywhere between 64 GB and 128 GB of memory. The program I will be working on will have 8 threads, each allocating memory blocks. The goal of the sleep() is for when I manage to alloc all available memory and one of the threads free()s some memory for another thread to alloc/calloc/realloc. – JoeManiaci Dec 09 '13 at 22:19
  • Ah, so I suppose your 10/11 times `char` allocations was for illustrative purposes only. I can only think of two reasonable actions on handling a `NULL`: total immediate abort, or return the NULL to a higher calling routine and let *it* handle this ... – Jongware Dec 09 '13 at 22:24
  • 2
    @JoeManiaci: This sounds like a recipe for deadlock where every process needs to wait on the others, each of which needs more memory to complete a large operation. Still, a typical 64-bit system very rarely runs out of memory in this fashion. In practice virtual memory and disk swapping usually insures that performance will have degraded to unbearable levels before malloc ever fails. – doynax Dec 09 '13 at 22:31
  • It is worth remembering that malloc and other allocators are just another abstraction layer. Moderm OS will go to extreme levels to ensure malloc and realloc never fails. This includes sleeping the entire thread until they can for-fill the request, even if this means paging out 64GB of memory from RAM to HDD. If you are really pushing to this extreme its probably way better to use an operating interface to MAP a huge section of ram directly and allocate it across threads yourself. The system will go unresponive long before malloc/realloc fails. – Myforwik Dec 09 '13 at 22:57

1 Answers1

1

Now I am assuming that you don't use temp = realloc(temp, 11*sizeof(char)); because if there is not enough memory you get a NULL ptr returned, thus leaving no way to access the original memory block.

Correct. This would cause a memory leak, if temp was your only reference to the memory block.

So would the below be a good way to handle a NULL pointer being returned?

No. That loop might loop forever. It's unlikely in this instance where you are simply trying to expand to 11 bytes. As H2CO3 said in the comments, if this fails you have serious issues.

If your system has run out of memory, it will likely become unstable. If only your process has fragmented the memory or run out of address space, no amount of waiting will help, unless other parts of your program are busy rectifying the problem.

When memory allocation fails, you either need a complex recovery strategy, or a clean exit strategy. Chances are high that trying to be clever about allocation will make your program extremely difficult to follow.

Unless you are writing something that will be part of a space probe or some other mission-critical device (which is unlikely to rely on dynamic memory anyway), your best strategy is to issue a helpful error message and cleanly exit.


Now, I just wrote all this and then saw your clarification in the comments about what you're actually doing. If you are happy that the sleep-loop solves your problems, then go for it, but put some code in there to detect outlandish waits and report them so you don't go crazy when debugging.

A richer solution would be to wrap this stuff in your own memory manager and use semaphore-driven queues or some other mechanism tailored to your program. Using sleeps is a little naive.

Also, I would not recommend allocating small blocks of data. If you do a lot of that, you may fragment your memory. If you need that, then you may need to do memory pooling in each thread and have them request larger blocks.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • All this data is coming off of a TCP connection. So I am more hoping to get a timeout because of a continued NULL return of realloc. It's the timeout I want to handle since I really have no choice but to try to receive all this data. – JoeManiaci Dec 09 '13 at 23:40