2

I quote a part of the definition of realloc in malloc(3) (http://man.he.net/?topic=malloc&section=all)

Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc().

And what if we call realloc with ptr that is not NULL, but also, was not returned by an earlier call to malloc(), calloc() or realloc()?

The behavior of realloc is undefined? Is there another answer?

duncan
  • 1,161
  • 8
  • 14
shaul boyer
  • 124
  • 3

3 Answers3

6

From http://en.cppreference.com/w/c/memory/realloc (emphasis mine):

Reallocates the given area of memory. It must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc.Otherwise, the results are undefined.

From the C99 standard (emphasis mine):

7.20.3.4 The realloc function

3 If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

What happens behind the scene if you hand over a pointer to realloc() or free() that was never given to you my malloc() is that your C library will make some assumptions like maybe being able to find and interpret some memory before the pointer as a block header telling it the length of the block, amongst other things. Because that isn't there, anything can happen.

Memory management will also assume this memory is mine now - If you don't get an immediate crash, you might be getting that stray pointer back from the next malloc() and have to deal with it...

Glibc will normally just barf at you because it tries to detect such cases (But the barfing is part of the undefined behavior as well).

tofro
  • 5,640
  • 14
  • 31
  • "Because that isn't there, anything can happen.". Probably it isn't there, in case the "illegal" pointer is to the area of the heap, it might be there, and I believe that this is the reason why the behavior is undefined as quoted from C99 in the first answer. – shaul boyer Jun 29 '16 at 19:11
  • @shaulboyer In computer memory, *there's always something there* - The dangerous case is when the *something* is interpreted as something it wasn't meant to. And that is what happens. – tofro Jun 29 '16 at 19:14
  • True, this is what I meant, and we can see that in the definition of realloc in C99 that I just glanced at. "if ... or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined." – shaul boyer Jun 29 '16 at 19:22
0

And what if we call realloc with ptr that is not NUL, but also, was not returned by an earlier call to malloc(), calloc() or realloc()?

It is plainly wrong.

A common beginner's error is attempting to use realloc() on objects, pointers to the first element of which weren't returned by a previous call to a function of the malloc() family. A typical example is passing an automatic array to a function which is supposed to modify its contents, possibly resize it as well by passing object's pointer to realloc. The code would compile, but the program would likely abort. lldb debugger would issue a message such as:

`malloc:  error for object 0x7fff6fbb16d6: pointer being realloc'd was not allocated`

gdb debugger would issue a similar, though slightly more complex message, such as:

`malloc.c:2869: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed. `
`Aborted (core dumped)` 

This is still a better case. By the book, behavior inferred by such calls is undefined. You may take a look at malloc.c of any operating system. Please, also see this SO post. This reference link may also be worth reading.

Community
  • 1
  • 1
user3078414
  • 1,942
  • 2
  • 16
  • 24