4
  • Platform: Linux 3.2.0 x86 (Debian Wheezy)
  • Compiler: GCC 4.7.2 (Debian 4.7.2-5)

I am wondering what will happen if I attempt to realloc() a pointer that has been incremented. For example

char *ptr = NULL;
size_t siz = 256;

ptr = malloc(siz);

ptr = realloc(ptr + 5, siz * 2);

What will the return value of the realloc() call be? I also know that realloc()'s documentation states that the pointer passed to it must have been returned by malloc(), calloc(), or realloc(). I am assuming that means I cannot realloc() an incremented pointer but I have been unable to verify that assumption.

John Vulconshinz
  • 1,088
  • 4
  • 12
  • 29
  • when you write "dereference" you actually mean "added to". Dereferencing means you apply the `*` or `[]` operators. – M.M Jun 20 '14 at 00:24

3 Answers3

4

That wouldn't work any predictable way, the results would be undefined. The 1st argument you pass to realloc or free must be returned by malloc, realloc or calloc, or it must be NULL.

In this case it is not true for ptr[5], because ptr[5] is uninitialized. You will also get a compile error or warning, because ptr[5] is not a pointer. But even if it was a pointer (e.g. char **ptr;), it would still be uninitialized, so the condition is false, and thus the results are undefined, and most probably the process would crash.

In this case it is not true for ptr + 5 either, because ptr + 5 is was not returned by malloc, realloc or calloc (but ptr was), and it's not NULL. The behavior is undefined in this case, most probably the process would crash.

pts
  • 80,836
  • 20
  • 110
  • 183
3

malloc family function allocates memory and then returns pointer to that block. ptr + 5 is not returned by malloc, so you can not pass it to realloc as it expects its first argument to be a pointer return by calloc or mallocor realloc itself. It will invoke undefined behavior.

C11: 7.22.3.3:

[...]Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
2

As pts says, the behavior is undefined. Here's a reference to the relevant documentation. I expect that you'll get a segfault, but you can't know how this will behave on your particular system without testing.

Trying out out on ideone.com gives you a memory error:

int main(void) {
    char *ptr = NULL;
    size_t siz = 256;

    ptr = malloc(siz);

    ptr = realloc(ptr + 5, siz * 2);

    return 0;
}

Yields:

*** Error in `./prog': realloc(): invalid pointer: 0x09dc900d ***
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x75e72)[0xb7641e72]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x275)[0xb7645ad5]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x28b)[0xb7645aeb]
./prog[0x80483e8]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5)[0xb75e58f5]
./prog[0x804840d]

Implementations of malloc differ from system to system, but the basic idea is that, somewhere, your OS has a list of pointers and associated regions of memory that have been malloc'd. When you call realloc, it looks for the address you've passed to it in its lookup table. It can't find it, so it gives up and dumps core.

Community
  • 1
  • 1
Patrick Collins
  • 10,306
  • 5
  • 30
  • 69