shared_ptr free memory

0

Witam,

Był podobny temat, ale 2 lata temu i dlatego decydowałem się na nowy wątek.

 using namespace std;

class B;
class A
{
public:
	A() {};
	~A()
	{
		cout << " A is destroyed" << endl;
	}
};
class B
{
public:
	B() : m_sptrA(nullptr) { };
	~B()
	{
		cout << " B is destroyed" << endl;
	}
	shared_ptr<A> m_sptrA;
};
//***********************************************************
void main()
{
	{
		shared_ptr<B> sptrB(new B);
		shared_ptr<A> sptrA(new A);

		//With this line order of destructors is replaced. 
		//sptrB->m_sptrA = sptrA; 
		
	}
	getchar();
}

Kiedy shared_ptr sptrA zostaje przypisane do pola m_sptrA, kolejność wywoływania destruktów zostaje zamieniona. Czy ktoś potrafiłby wytłumaczyć jaki mechanizm się za tym kryje ?

1

Mechanizm iluzji. Kolejność wywołania destruktorów nie ulega zmianie (dla zmiennych o automaycznym czasie życia). Destruktor sptrA wykonuje się przed destruktorem sptrB, ale ponieważ licznik referencji (refcount) w tym momencie wynosi 2, obiekt typu A, na który wskazuje sptrA nie jest niszczony. Jest niszczony dopiero gdy znika ostatnia referencja, która znika podczas destrukcji B (po wywołaniu ~B()).

1

int main, nie void main.

@kq wyjaśnił już dlaczego, ale żeby zobrazować:

  1. Gdy ta ostatnia linia jest zakomentowana, kolejność wywołania destruktorów będzie
~shared_ptr<A>()
    ~A()
~shared_ptr<B>()
    ~B()
        ~shared_ptr<A>()
  1. Gdy ostatnia linia nie będzie zakomentowana
~shared_ptr<A>()
~shared_ptr<B>()
    ~B()
        ~shared_ptr<A>()
            ~A()
0

Ok. Teraz rozumiem. Czyli na samym początku wywołuje się destruktor

~shared_ptr<A> 

i jeżeli refcount jest równy 1, destruktor samego obiektu.

Dzięki wielkie!

0

Można uniknąć tego problemu przez przechowywanie tylko jednej kopii danego shared_ptr (czyli nie wykorzystywać cechy “shared” z shared_ptr), a pozostałe trzymać jako weak_ptr.

To samo można osiągnąć przez użycie unique_ptr zamiast shared_ptr i gołego wskaźnika zamiast weak_ptr, tylko wtedy trzeba pamiętać by nie robić delete na tym gołym wskaźniku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1