Понятие о количестве ссылок и циклических ссылках в C ++ - PullRequest
0 голосов
/ 16 января 2020

Я знаю, как используется weak_ptr, я прочитал следующий пост:

О «циклической ссылке», я использовал слабый_птр, но утечка памяти все же произошла

Но есть концепция, которую я пока не могу понять.

Я покажу, как shared_ptr создан и выпущен, насколько я понимаю:


1. shared_ptr pa создано

reference_count из pa должно быть 0. Потому что нет shared_ptr указывает на pa.

{/*scope 1*/

  shared_ptr<int> pa;
  // reference_count_pa = 0
}

2. Я назначаю новые shared_ptr<int> pb для pa в другой области

{/*scope 1*/

  shared_ptr<int> pa;

  {/*scope 2*/

    shared_ptr<int> pb = pa;
    // reference_count_pa = 1
    // reference_count_pb = 0
  }
}

reference_count из pa должно быть 1, поскольку shared_ptr pb указывает на pa.

reference_count из pb должно быть 0, поскольку shared_ptr не указывает на pb.

3. Теперь, простое Circular Reference:

, как показано в О «круговой ссылке», я использовал слабый_птр, но утечка памяти все же произошла :

{/*scope 1*/

  shared_ptr<int> pa;

  {/*scope 2*/

    shared_ptr<int> pb = pa;
    pa = pb; //circular reference
    // reference_count_pa = 1
    // reference_count_pb = 1
  }
}

reference_count из pa должно быть 1, потому что shared_ptr pb указывает на pa

reference_count из pb должно быть 1, поскольку shared_ptr pa указывает на pb

4. В конце scope 2

pb удаляется, потому что программа выходит из scope 2.

reference_count из pa равно 0, потому что нет shared_ptr указывает на pa.

reference_count из pb по-прежнему 1.

5. В конце scope 1

reference_count из pb означает 0 сейчас, потому что shared_ptr не указывает на pb.


Вышеуказанные шаги reference_count, насколько я понимаю.

pa и pb удаляются нормально.

Я в замешательстве.

Может кто-нибудь исправить мою ошибку в вышеуказанных шагах ?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 16 января 2020

Кто-нибудь исправляет мою ошибку на предыдущем шаге?

Во-первых, это не круговая ссылка. Во-вторых, в вашем коде нет подсчета ссылок, потому что у вас нет int для подсчета ссылок.

Циркулярная ссылка имеет вид

struct Node {
    std::shared_ptr<Node> next;
};

int main() {
    std::shared_ptr<Node> a = std::make_shared<Node>();
    std::shared_ptr<Node> b = std::make_shared<Node>();

    a->next = b;
    b->next = a;
}
0 голосов
/ 16 января 2020

Вы имели в виду use_count, когда писали reference_count? Последний не может быть найден в cpp -референции.

Ответ: shared_ptr подсчитывает количество всех (этого и других) управляемых указателей, которые указывают на один и тот же объект (указатель). Следовательно, все управляемые указатели, указывающие на один и тот же объект, будут возвращать один и тот же use_count. (Это соответствует вашему выводу 2.).

Ваша "круговая" ссылка в 3 - не круговая ссылка, а два общих указателя, указывающих на ничто. Я рекомендую std::make_shared> для создания (управляемого) Управляемый объект должен быть общим указателем. Кстати, недельный указатель указывает на управляемый объект, который знает о существовании этого объекта.

Просто прочитайте руководство, https://en.cppreference.com/w/cpp/memory/shared_ptr Здесь вы найдете описание use_count:

long use_count() const noexcept;

Возвращает количество различных экземпляров shared_ptr (включая), управляющих текущим объектом. Если нет управляемого объекта, возвращается 0.

...