Search code examples
cpointersrealloc

Using original pointer after realloc?


I was reading Richard Reese's new (May 2013) O'Reilly book "Understanding and Using C Pointers", and I have a question about some code therein, on page 87.

if (++length > maximumLength) {
    char *newBuffer = realloc (buffer, maximumLength += sizeIncrement);

    if (newBuffer == NULL) {
        free (buffer);
        return NULL;
    }

    currentPosition = newBuffer + (currentPosition - buffer);
    buffer = newBuffer;
}

I hope the names of the variables are self-explanatory; if context is needed, I will edit to provide the entire chunk of code and not just this excerpt.

My question is about the line currentPosition = newBuffer + (currentPosition - buffer);. My understanding of realloc() is that when the new allocation succeeds, the originally allocated memory is freed. If that is correct, then the line in question is using dangling pointers, innit? Both buffer and currentPosition on the RHS of that expression are pointers to memory that has been freed.

My instinct would be to rewrite this to avoid using the dangling pointers by using length, which after all is already around. I want to replace those last two lines with:

buffer = newBuffer;
currentPosition = buffer + length;

However, presumably the code as written works because the two pointers still hold addresses (albeit of garbage), and the offset between those two addresses can still be calculated as a way of reassigning currentPosition. So am I being merely persnickety in feeling uneasy about this?

To generalize the question: once a pointer is dangling, is it safe to use the address contained in the pointer for any purpose, such as calculating offsets? Thanks.


Solution

  • once a pointer is dangling, is it safe to use the address contained in the pointer for any purpose, such as calculating offsets?

    No, it is not safe. After free the pointer value is an invalid address and an invalid address cannot be used for pointer arithmetic without invoking undefined behavior.