What is the state of p1, p2 after compiling and running below C snippet code?
char *p1 = malloc(5);
char *p2 = p1 - 3;
*p2 = '\0';
What is the state of p1, p2 after compiling and running below C snippet code?
char *p1 = malloc(5);
char *p2 = p1 - 3;
*p2 = '\0';
If you were turning this C code directly into simple machine code on a simple machine, then char *p2 = p1 - 3;
would set p2
to point to three bytes earlier in memory than p1
, and *p2 = '\0'
would write a zero to an improper location. We do not know what is at that location, so we cannot say what the effect is.
However, modern compilers generally do not turn C code directly into simple machine code. They interpret the C code and perform complicated optimizations on it. Because of this, understanding what happens requires using the C standard or documentation for the compiler being used.
What does the C standard tell us about this code? For p1 - 3
, the rules about addition with a pointer in C 2018 6.5.6 8 apply:
When an expression that has integer type is added to or subtracted from a pointer,… If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
Because p1
points to an element of object (which may be used as an array) provided by malloc
, and p1 - 3
does not point to an element of that array, the behavior is not defined by the C standard. Therefore, if we are using the C standard as a basis for understanding, once p1 - 3
is evaluated, we cannot say what the behavior of the program or the state of p1
and p2
is.
p1 points to the begin of the allocated memory block. p2 contains the address of the byte three bytes before this block. So the third line will modify a byte outside of the memory block, which will either overwrite some data allocated by other code or corrupt the memory management structures.