What are the odds that realloc will fail?

Does this happen when he runs out of free memory, similar to malloc , or there may be other reasons?

+8
c memory-management realloc
source share
4 answers

Any of the distribution functions ( malloc , realloc , calloc and POSIX, posix_memalign ) may fail for any of the following reasons, and possibly others:

  • You have used all of your virtual address space, or at least its useful part. On a 32-bit machine, there are only 4 GB addresses, and perhaps 1 GB or so is reserved for use by the OS kernel. Even if your computer has 16 GB of physical memory, one process cannot use more than it has addresses.
  • You did not use your virtual address space, but you fragmented it so much that there is no continuous range of addresses of the requested size. This can happen (on a 32-bit machine) if you successfully allocate 6 512 MB blocks, free all the others, and then try to allocate a 1 GB block. Of course, there are many other examples with smaller memory sizes.
  • Your computer has run out of physical memory, either because your own program used it all, or other programs running on the machine that used it all. Some systems (Linux in the default configuration) will be surpassed, which means that malloc will not work in this situation, but instead, the OS will kill one or more programs later when it turns out that there is actually not enough physical memory. But on reliable systems (including Linux with overcommit disabled), malloc will fail if there is no physical memory left.

Please note that, strictly speaking, distribution functions are allowed at any time for any reason. Failure minimization is a quality implementation problem. It is also possible that realloc may fail even if the size of the object is reduced; this can happen in implementations that strictly separate size distributions. Of course, in this case, you could just continue to use the old (larger) object.

+10
source share

You should think that realloc works like this:

 void *realloc(void *oldptr, size_t newsize) { size_t oldsize = __extract_size_of_malloc_block(oldptr); void *newptr = malloc(newsize); if (!newptr) return 0; if (oldsize > newsize) oldsize = newsize; memcpy(newptr, oldptr, oldsize); free(oldptr); return newptr; } 

An implementation can perform specific actions more efficiently than an implementation, but an implementation that works exactly as shown is 100% correct. This means that realloc(ptr, newsize) can fail at any time malloc(newsize) . in particular, it may fail even if you reduce the selection.

Now, on modern desktop systems, there is a strong example for not trying to recover from malloc crashes, but instead wrap malloc in a function (usually called xmalloc ) that immediately terminates the program if malloc fails; Naturally, the same argument applies to realloc . The point is this:

  • Desktop systems often run in "overcommit" mode, where the kernel will happily transfer more address space than the RAM + swap operation can provide, assuming that the program will not actually use all of this. If a program tries to use all of this, it will be forced to terminate. On such systems, malloc will fail if you run out of address space, which is unlikely for 32-bit systems and almost impossible on 64-bit systems.
  • Even if you are not in overcommit mode, the likelihood that the desktop system will have so much RAM and swap that long before you fail malloc , the user will be fed up with his thrashed disk and forcibly terminate your program.
  • There is no practical way to test recovery from distribution failure; even if you had a gasket library that could precisely control which calls to malloc failed (such gaskets are complicated at best, impossible to create depending on the OS), you will need to check the order 2 N where N is the number of calls in malloc in your program.

Arguments 1 and 2 do not apply to embedded or mobile systems (for now!), But argument 3 still remains there.

Argument 3 applies only to programs in which distribution errors must be checked and propagated at each call site. If you're so lucky to use C ++ as it is intended to be used (i.e. with exceptions), you can rely on the compiler to create error recovery paths for you, so the testing load is greatly reduced. And in any higher-level language that you should currently use, you have both exceptions and a garbage collector, which means you can't worry about distribution failures, even if you want.

+4
source share

I would say that this is basically a concrete implementation. Some implementations are very likely to fail. Some of them may have other parts of the program if they are not executed. Always defend yourself and see if it works.

And don't forget to free the old pointer that you were trying to redistribute.

 ptr=realloc(ptr,10); 

There is ALWAYS a possible memory leak.

Always do it something like this:

 void *tmp=ptr; if(ptr=realloc(ptr,10)==NULL){ free(tmp); //handle error... } 
+1
source share

You have two questions.

The chances of malloc or realloc failing are negligible in most modern systems. This only happens when you have run out of virtual memory. Your system will not be able to access memory, not reserve it.

Error Wrt realloc and malloc almost equal. The only reason realloc may fail is because you give it a bad argument, that is, memory that was not allocated using malloc or realloc or previously free d.

Edit: In response to comment R. Yes, you can configure your system so that it does not fail during distribution. But above all, AFAIK, this is not the default. This requires privileges that must be configured in this way, and as an application programmer, you cannot count on. Secondly, even if you have a system configured in this way, it will only be a mistake when your free swap space is eaten. Typically, your machine will be unusable long before that: it will perform mechanical calculations on your hard drive (AKA swap).

0
source share

All Articles