Идентификаторы, дескрипторы и время жизни ресурсов
Разбор понятий идентификатор, дескриптор, адрес и время жизни ресурса. Разграничение владельца ресурса и временного доступа на гипотетическом примере без утверждений о контрактах конкретной среды.

Назначение
Программа, работающая с оперативной памятью, должна называть участки данных и определять, кто отвечает за их освобождение. Идентификатор, дескриптор, адрес и время жизни ресурса решают разные задачи, и смешение этих понятий приводит к утечкам памяти и обращениям к освобождённым областям. Материал разбирает каждое понятие отдельно и показывает их взаимодействие на гипотетическом примере, не привязанном к конкретной среде выполнения.
Читатель получает определения, которые можно сопоставить с документацией любого языка или API: где именно начинается ответственность за ресурс, где заканчивается временный доступ и что происходит, если одна из этих границ нарушена. Примеры в тексте обозначены как гипотетические и не описывают поведение конкретной платформы.
Идентификатор и дескриптор
Идентификатор — это имя, которое программа использует для ссылки на объект: имя переменной, ключ записи, номер элемента списка. Дескриптор выдаётся системой или средой выполнения как токен доступа к ресурсу, который сам по себе не раскрывает структуру данных. Например, дескриптор кучи памяти позволяет обращаться к выделенным в ней блокам, не зная их физических адресов.
При этом дескриптор не обязан быть числовым токеном, не обязан отличаться от любого адреса и не обязан закрываться через единую универсальную операцию. Его свойства задаёт контракт конкретного API. Идентификатор может называть ресурс, за освобождение которого программа несёт ответственность, тогда как другие идентификаторы лишь указывают на чужие объекты. Роль идентификатора определяется не его видом, а тем, что программа с ним делает.
Адрес и представление данных
Адрес указывает конкретное место в адресном пространстве процесса. Если дескриптор отвечает на вопрос «какой ресурс», то адрес отвечает на вопрос «где именно». В гипотетической схеме программа создаёт кучу с дескриптором hHeap, а внутри неё размещает буфер изображения с начальным адресом BuffBmp. Вторая куча с дескриптором hHeap2 и адресом Memr2 хранит буфер переменных.
Здесь дескриптор выбирает кучу, адрес выбирает место внутри неё. Важно, что эта схема иллюстрирует роли понятий, а не утверждает точный порядок освобождения буферов или гарантию их существования до закрытия кучи. В других схемах адрес может быть единственным идентификатором, а дескриптор вообще отсутствовать.
Владелец и временный доступ
Владелец ресурса — тот, кто обязан его освободить, когда ресурс больше не нужен. Временный доступ, или заимствование, разрешает использовать ресурс в ограниченный период без передачи ответственности за его освобождение. Указатель на буфер, переданный в функцию для чтения, является примером заимствования: функция читает данные, но не освобождает буфер.
Время жизни локальной переменной зависит от языка и модели области видимости, а не от универсального правила «от объявления до конца блока». Указатель может оставаться валидным независимо от того, сохранил ли получатель оригинальный дескриптор кучи. Контракт о владении, а не механика передачи указателя, определяет, кто и когда освобождает ресурс.
Гипотетический пример жизненного цикла
Представим, что программа создаёт буфер изображения, получает на него дескриптор и передаёт этот дескриптор в модуль обработки. Модуль использует буфер, выполняет операции и возвращает результат, не освобождая буфер. Владелец, то есть создавшая программа, освобождает буфер после получения результата. Если модуль обработки ошибочно освобождает буфер сам, владелец получает уже освобождённый ресурс.
Такой сценарий показывает, почему важно зафиксировать в контракте, кто освобождает ресурс. Двойное освобождение и обращение к освобождённой памяти являются нарушением контракта о владении. Наблюдаемые последствия такого нарушения зависят от конкретной среды и не сводятся к одному универсальному результату.
Ограничения и порядок освобождения
Разграничение ролей снижает риск ошибок, но не устраняет большинство проблем с временем жизни. Порядок освобождения ресурсов определяется зависимостями между ними и документированной моделью времени жизни, а не общим правилом. Ресурс, от которого зависит другой ресурс, обычно освобождается позже.
Чёткое понимание, кто владелец, кто заимствует и когда ресурс перестаёт существовать, позволяет проектировать программы, в которых освобождение происходит один раз и в правильном порядке. Это не гарантия отсутствия ошибок, но условие, без которого корректное управление ресурсами невозможно.