-3
#include <stdio.h>
#include <stdlib.h>

main()
{
    int *p = (int *)malloc(sizeof(int));
    int *q = (int *)realloc(p,sizeof(int));
    *p = 3;
    *q = 9;
    if (p == q)
        printf("%d %d", *p, *q);

}

when i run this it print 9 9 in GCC. Can someone explain the behavior of this code?

developer.ahm
  • 180
  • 10
  • 1
    Your `realloc()` call is unlikely to change the pointer `p`, so the call is equivalent to `q = p`. – Iharob Al Asimi Nov 10 '17 at 12:49
  • What do you expect? `9` is a valid integer, so it can be the result. – harper Nov 10 '17 at 12:49
  • 1
    @IharobAlAsimi No. Successful `realloc()` always invalidates the original pointer. – EOF Nov 10 '17 at 12:50
  • 2
    Using a pointer after a successful `realloc()` on it is *undefined behavior*, end of story. –  Nov 10 '17 at 12:50
  • 3
    ..and please don't ask for UB to be explained further:( – Martin James Nov 10 '17 at 12:52
  • The code isn't even valid C++ (removed that tag) and in C, it's a deprecated feature to leave out the return type of a function. This should be `int main(void)`! –  Nov 10 '17 at 13:01

1 Answers1

7

What does the standard say?

Going strictly by the standard, your program exhibits undefined behavior (C standard, 7.22.3.5):

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.

The two objects involved in realloc are not the same - the new one is allocated, and you know its contents are the same as the old one, and the old one is destroyed. Your dereference of p is access to an object outside its lifetime, which is undefined.

What (probably) happens in practice here?

realloc can move the memory area if necessary, but does not have to move the memory area.

In this situation, both allocations are of the same size (sizeof(int)). realloc very likely realizes this and doesn't move the memory area at all.

As a result, p == q.

PS: "probably" because the behavior is undefined. Your compiler might just analyze the realloc code path and notice that the only legal way the program can work is if realloc doesn't move the pointer, and optimizes to q = p instead. You'd need to investigate the assembly generated to really find out.

Treeston
  • 390
  • 1
  • 7