Понимание поведения висячего указателя в этом случае
У меня есть указатель, и по умолчанию он несет NULL, затем он ожидает какого-то события и получает значение, если событие произойдет, позже я освобождаю указатель где-то еще, но даже после освобождения указателя я не делаю его NULL, поэтому он все еще продолжает ссылаться та же самая область памяти, и я знаю, что следующий вызов malloc мог бы выделить этот кусок памяти для некоторого другого запроса памяти!
pointer_type *p = NULL;
while (process_get_wakeup(//some logic//)) {
while ((qelem = (void*)process_dequeue(//some logic//)) != NULL) {
p = (pointer_type *)qelem;
}
.
.
//goes into a loop of calls where free(p) is also done!
.
.
//Printing value of p as %p gives this : 0xFF00000000
РЕДАКТИРОВАТЬ: я уже знаю, не то, как мы должны это делать, и я не могу ожидать, чтобы сохранить то же значение, которое может быть использовано для чего-то другого сейчас, но я хочу знать, почему только конкретное значение р видел я!
Имеет ли это значение: 0xFF00000000 какое-то особое значение?
2 ответа
Наоборот - указатель не сохраняет свое значение после free
,
Стандарт С говорит, что как только объект free
d или, в более общем смысле, его время жизни заканчивается, значения всех указателей, указывающих на объект, становятся неопределенными, и использование такого неопределенного значения может привести к неопределенному поведению, даже если оно просто печатало значение. То, что он выглядит так, как будто он сохраняет свое первоначальное значение, никоим образом не гарантируется.
Это позволяет компилятору C выполнять оптимизацию внутри вашей функции. Например, если он использовал один регистр процессора, чтобы сохранить значение p
, после free(p)
При вызове компилятор знает, что регистр теперь может использоваться для чего-то другого, например, для хранения результатов промежуточных вычислений других операций, и его значение не нужно сохранять до тех пор, пока ему не будет присвоено новое значение.
Что касается адреса памяти двух разных объектов, являющихся одинаковыми - это возможно, если они не живы одновременно. Один объект будет иметь постоянный адрес в течение всего времени его существования. Что происходит после его жизни, не уточняется. malloc
часто реализуется в виде списка свободных блоков, а в последнее время free
Блок d, вероятно, будет повторно использован первым.
позже я освобождаю указатель где-то еще? Убедитесь, что вы свободны p
только когда ему присваивается динамический адрес памяти, в противном случае это приводит к неопределенному поведению.
p = NULL; /* now it's points to NULL */
p = malloc(SIZE); /* malloc() may give same previews memory location or may not */
Из стандарта C, раздел 6.2.4
Время жизни объекта - это часть выполнения программы, в течение которой для него гарантированно хранится память. Объект существует, имеет постоянный адрес и сохраняет свое последнее сохраненное значение в течение всего срока его службы. Если на объект ссылаются вне его времени жизни, поведение не определено. Значение указателя становится неопределенным, когда объект, на который он указывает (или только что прошедший), достигает конца своего времени жизни.
А также
Я не могу ожидать, чтобы сохранить то же значение, которое может быть использовано для чего-то другого сейчас?
ты не можешь заставить malloc()
не возвращать тот же старый адрес памяти после освобождения. Освобожденная память больше не принадлежит вашей программе, в следующий раз, когда ваш процесс попытается снова выделить память, malloc()
может вернуть тот же адрес (не значение) или нет.