Ваш код правильный.Обратная последовательность может сработать, но если это сработает, это будет случайным.
Причина в том, что free(st)
освобождает память, в которой хранится объект *st
.Указатель st->base
хранится в части этой самой памяти.Предположим, что какая-то другая задача или поток приобрели ту же память, как только она была освобождена.Что тогда?То есть, что произойдет, когда free(st->base)
будет в конце концов вызвано?
Ответ: что произойдет, не определено.
Даже если бы все еще можно было получить адрес из st->base
(иэто может быть невозможно), этот адрес мог быть перезаписан произвольными данными, и в этом случае free(st->base)
- при интерпретации произвольных данных как адреса - попросит операционную систему освободить ... ну, вы не знаете что будет запрашивать операционную систему для освобождения.Вряд ли стоит ожидать хороших результатов в этом случае.
Вы хорошо поработали.Ваша последовательность правильная.
ДОПОЛНИТЕЛЬНЫЕ СООБРАЖЕНИЯ
В целях безопасности ядра современных операционных систем иногда автоматически перезаписывают освобожденную память нулевыми или случайными данными.Кроме того, они иногда отменяют доступ программы к аппаратной странице , по которой была (фактически) адресована освобожденная память, или ужесточают границы, в пределах которых разрешен доступ.Некоторые из них более вероятны, чем другие, но я видел, как минимум два из трех случаев.Дело в том, что ядро может делать такие вещи немедленно, раньше, позже или вообще не делать этого, как предпочитает ядро, в соответствии с последними алгоритмами управления памятью и безопасности ядра, поскольку ваша программа не должна заботиться о том, что происходит с освобождениемпамять после того, как программа освободила ее.