Подтвердить что ты не робот

Предоставляет ли компилятор возможность переработать освобожденные переменные указателя?

Утверждается, что

компилятор может повторно использовать переменную указателя для какой-либо другой цели после освобождения realloc, поэтому у вас нет гарантии, что она имеет то же значение, что и раньше,

т

void *p = malloc(42);
uintptr_t address = (uintptr_t)p;
free(p);

// [...] stuff unrelated to p or address

assert((uintptr_t)p == address);

может выйти из строя.

Приложение С11 J.2 гласит

Значение указателя, которое ссылается на пространство, освобожденное вызовом свободной или используется функция realloc (7.22.3) [is undefined]

но приложение, конечно, не является нормативным.

Приложение L.3 (которое является нормативным, но необязательным) говорит нам, что если

Значение указателя, которое ссылается на пространство, освобожденное вызовом free или realloc (7.22.3).

результат разрешен для критического поведения undefined.

Это подтверждает утверждение, но я хотел бы видеть соответствующую цитату из стандартного, а не приложения.

4b9b3361

Ответ 1

Когда объект достигает конца своего срока службы, все указатели на него становятся неопределенными. Это относится и к переменным объемной области, и к malloced памяти одинаково. Применяемый пункт, в C11, 6.2.4: 2.

Время жизни объекта - это часть выполнения программы, в течение которой хранилище гарантировано зарезервировано для него. Объект существует, имеет постоянный адрес и сохраняет свое последнее сохраненное значение на протяжении всего его жизненного цикла. Если объект упоминается вне его срока службы, поведение undefined. Значение указателя становится неопределенным, когда объект, на который он указывает (или только что прошел), достигает конца своего срока службы.

Использование неопределенной памяти для чего-либо, включая, по-видимому, безвредное сравнение или арифметику, - это поведение undefined (в C90; более поздние стандарты усложняют этот вопрос, но компиляторы продолжают рассматривать использование неопределенной памяти как поведение undefined).

В качестве примера, как насчет следующей программы печати, что p и q являются разными и одинаковыми? Результаты выполнения с различными компиляторами показаны здесь.

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char *argv[]) {
  char *p, *q;
  uintptr_t pv, qv;
  {
    char a = 3;
    p = &a;
    pv = (uintptr_t)p;
  }
  {
    char b = 4;
    q = &b;
    qv = (uintptr_t)q;
  }
  printf("Roses are red,\nViolets are blue,\n");
  if (p == q)
    printf ("This poem is lame,\nIt doesn't even rhyme.\n");
  else {
    printf("%p is different from %p\n", (void*)p, (void*)q);
    printf("%"PRIxPTR" is not the same as %"PRIxPTR"\n", pv, qv);
  }
}