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

Что происходит со слабым_ptr, когда его shared_ptr уничтожен?

Кажется, что weak_ptr как-то просто знает, когда shared_ptr ссылки были уничтожены. Как так? Существует ли постоянная связь или что-то еще?

Возьмите следующий код, например:

weak_ptr<int> test() {
    shared_ptr<int> foo{new int};

    return foo;
}

int main() {
    auto foo = test();

    cout << foo.expired() << endl;
}

Я бы ожидал segfault, когда weak_ptr<int> отправляется проверять состояние shared_ptr<int>, но его нет. weak_ptr<int> правильно идентифицирует память как освобожденную. Как это известно?

4b9b3361

Ответ 1

A std::shared_ptr создается с использованием двух частей памяти:

  • Блок ресурсов: он содержит указатель на фактические базовые данные, например. 'INT *'

  • Управляющий блок: содержит информацию, относящуюся к shared_ptr, например, счетчики ссылок.

(Иногда они выделяются в едином блоке памяти для эффективности, см. std::make_shared)

Контрольный блок также хранит подсчет ссылок для weak_ptr. Он не будет освобожден до тех пор, пока последний weak_ptr не выйдет из области видимости (количество ссылок на указатель слабой ссылки падает до нуля).

Итак, weak_ptr будет знать, что он истек, потому что у него есть доступ к этому блоку управления, и он может проверить, что подсчет ссылок для shared_ptr