carrayspointersundefined-behaviorpointer-arithmetic

When is pointer subtraction undefined in C?


char *buf = malloc(bufsize)
char *ptr = buf;
…
while(condition) {
    ptrdiff_t offset = ptr - buf;    // <========== THIS LINE

    // offset will never be negative because we only ever *increase* ptr
    if ((size_t)offset > bufsize) {
        // we need more room
        bufsize += 128;
        buf = realloc(buf, bufsize);
        ptr = buf + offset;  // buf might be in a completely new location
    }
    *ptr++ = …  // write this byte
}

Is this valid or undefined?

I would have assumed that it's valid, but I read something about it being undefined, so I googled it. These links seem to inescapably claim it's undefined:

However, no mention of it is made in these SO questions:

These all talk about not two pointers being in the same "array". Does that actually mean a plain old C array on the stack?

If it is undefined, it seems very odd to me… Why force me to carry along a counter variable when I have access to one constant pointer and one moving pointer?


Solution

  • Pointers into a block of memory returned by malloc count as being into the same array:

    7.22.3 Memory management functions

    1 - The pointer returned [from malloc] if the allocation succeeds [...] may be assigned to a pointer to any type of object [...] and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).