Использование исходного указателя после realloc?

Я читал книгу Ричарда Ризса (май 2013 г.) книгу О'Рейли "Понимание и использование указателей С", и у меня есть вопрос о некотором коде в ней, на странице 87.

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

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

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

Я надеюсь, что имена переменных не требуют пояснений; если контекст необходим, я отредактирую, чтобы предоставить весь фрагмент кода, а не только этот фрагмент.

Мой вопрос о линии currentPosition = newBuffer + (currentPosition - buffer);. Мое понимание realloc() заключается в том, что когда новое распределение успешно завершается, изначально выделенная память освобождается. Если это правильно, тогда строка, о которой идет речь, использует оборванные указатели, не так ли? Оба buffer и currentPosition в RHS этого выражения являются указателями на память, которые были освобождены.

Моим инстинктом было бы переписать это, чтобы избежать использования оборванных указателей, используя length, который, в конце концов, уже существует. Я хочу заменить эти последние две строки:

buffer = newBuffer;
currentPosition = buffer + length;

Однако, предположительно, код, написанный, работает, потому что два указателя по-прежнему содержат адреса (хотя и от мусора), а смещение между этими двумя адресами все равно можно рассчитать как способ переназначения currentPosition. Так что я просто безрассудно чувствую себя неловко?

Чтобы обобщить вопрос: как только указатель свисает, безопасно ли использовать адрес, содержащийся в указателе, для любых целей, например вычисления смещений? Благодарю.

Ответ 1

как только указатель свисает, безопасно ли использовать адрес, содержащийся в указателе, для любых целей, например вычисления смещений?

Нет, это небезопасно. После free значение указателя является недопустимым адресом, а недопустимый адрес не может использоваться для арифметики указателя без вызова поведения undefined.

Ответ 2

Безопасно использовать оборванный указатель (например, для "арифметики указателя" ), если вы не пытаетесь разыменовать указатель (т.е. применить оператор *).