Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use realloc?

Some time ago a friend of mine told me not to use realloc because it's unsafe, but he couldn't tell me why, so I made some research on the subject and the nearest references to my doubt were:

  1. First
  2. Second

I want to know if I can continue to use realloc in my code or if it's unsafe is there any other way to reallocate memory?

like image 604
k3oy Avatar asked Jan 30 '12 22:01

k3oy


People also ask

Does realloc destroy data?

Will I lose my data? No, the data will be copied for you into the new block that the returned p points at, before the old block is freed. This all happens before realloc returns, so the new p points to your data still.

Is malloc unsafe?

Yes, it is unsafe. You need to check the return value from malloc . This piece of code is not security itself for x and y never changes. Another, more subtle problem is that x * y might overflow, in which case you'll likely allocate less than you intend.

Should you free after realloc?

In short, no. Once you call realloc() , you do not have to free() the memory addressed by pointer passed to realloc() - you have to free() the memory addressed by the pointer realloc() returns.

Why do we use realloc?

The function realloc is used to resize the memory block which is allocated by malloc or calloc before. Here, pointer − The pointer which is pointing the previously allocated memory block by malloc or calloc. size − The new size of memory block.


2 Answers

It's perfectly safe to use realloc. It is the way to reallocate memory in a C program.

However you should always check the return value for an error condition. Don't fall into this common trap:

p = realloc(p, new_size); // don't do this!

If this fails, realloc returns NULL and you have lost access to p. Instead do this:

new_p = realloc(p, new_size);
if (new_p == NULL)
    ...handle error
p = new_p;
like image 125
David Heffernan Avatar answered Sep 29 '22 01:09

David Heffernan


The first of the two linked article raises two complaints above and beyond the "check the call succeeded" points already raised here.

When this is done, the old contents are discarded and left in memory somewhere. For secure memory applications where it is important to erase all traces of data, this behavior is inappropriate.

This is a valid point if you happen to be storing sensitive data (e.g. private keys, unhashed(!) passwords etc.) and want to make it harder for exploits to recover the data or other processes on the system to steal the data.

Since it moves memory around, any old pointers to that memory become invalid and could cause the program to crash or otherwise misbehave.

This point seems like nonsense to me. Their proposed solution is no better, they malloc(), copy and then free() the original which has the same net effect - the address has changed. If you wanted to avoid moving the memory you might be able to use some platform specific calls to do that, if you arranged for there to be sufficient free address space near them. If you knew a priori how much address space to reserve then you'd probably not be thinking of calling realloc() in the first place though!

If you're gambling on realloc() never moving, always growing then you've probably got bigger problems to worry about anyway and switching to malloc() + copy + free() can't possibly solve that.


Besides the "check your return value properly point", the most interesting point from the second article is a warning about:

Do not realloc your buffer by 1 byte at a time.

they warn:

This is guaranteed to churn your memory heap

This is a potentially valid point, but it's not a criticism of realloc() itself; the same would happen if you used malloc()+copy+free(). The real fix is to grow buffers sensibly regardless of how you grow them or better yet allocate in correct sized chunks up front.

They also have a point about

Using realloc to return memory to the system.

They're correct here in that using any size other than 0 might not actually make a return. It probably makes things no worse, but this usage still seems like an example of premature "optimisation". The fix again is to use sensible sized allocations to begin with.

Sort answer: it's not unsafe, but it's not a magical solution to all your problems either.

like image 29
Flexo Avatar answered Sep 28 '22 23:09

Flexo