Sobes.tech
Middle

std::shared_ptr'da referans sayacı nasıl çalışır?

sobes.tech yapay zeka

AI'dan gelen yanıt

std::shared_ptr içindeki referans sayacı, ayrı bir nesnede saklanır: kontrol bloğunda (control block).

Kontrol bloğu şu durumlarda oluşturulur:

  • Bir gösterge (pointer) kullanılarak ilk std::shared_ptr oluşturulduğunda.
  • Özelleştirilmiş bir silici veya ayırıcı ile std::shared_ptr oluşturulduğunda.
  • std::make_shared veya std::allocate_shared kullanıldığında.

Bu kontrol bloğu en az iki sayacı içerir:

  1. Güçlü referans sayacı (strong count): Bir std::shared_ptr oluşturulduğunda veya kopyalandığında artar. Bir std::shared_ptr yok edildiğinde azalır. Bu sayaç sıfıra ulaşınca, yönetilen nesne serbest bırakılır.
  2. Zayıf referans sayacı (weak count): Bir std::weak_ptr, bir std::shared_ptr'dan oluşturulduğunda artar. Bir std::weak_ptr yok edildiğinde azalır. Her iki sayaç da — güçlü ve zayıf — sıfıra ulaşınca, kontrol bloğu serbest bırakılır.

std::make_shared kullanımı, doğrudan new ile oluşturulmaya göre tercih edilir çünkü nesne ve kontrol bloğu tek bir bellek bloğunda tahsis edilebilir, bu da performansı artırır ve parçalanmayı azaltır.

Sayaçlar atomiktir, bu da std::shared_ptr'ın çok iş parçacıklı senaryolarda güvenli olmasını sağlar, ancak yönetilen nesneye erişim varsayılan olarak senkronize edilmemiştir.

Örnek:

#include <iostream>
#include <memory>

struct MyObject {
    int data;
    MyObject(int d) : data(d) {
        std::cout << "MyObject(" << data << ") oluşturuldu\n";
    }
    ~MyObject() {
        std::cout << "MyObject(" << data << ") yok edildi\n";
    }
};

int main() {
    std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
    // güçlü sayaç: 1, zayıf sayaç: 0

    {
        std::shared_ptr<MyObject> ptr2 = ptr1;
        // güçlü sayaç: 2, zayıf sayaç: 0

        std::weak_ptr<MyObject> weak_ptr = ptr1;
        // güçlü sayaç: 2, zayıf sayaç: 1

        if (auto locked_ptr = weak_ptr.lock()) {
            // güçlü sayaç: 3, zayıf sayaç: 1 (geçici lock içinde)
            std::cout << "Nesne verisi: " << locked_ptr->data << std::endl;
        }
        // güçlü sayaç: 2, zayıf sayaç: 1
    } // ptr2 kapsam dışına çıktı
    // güçlü sayaç: 1, zayıf sayaç: 1

    // Nesne henüz yok edilmedi, çünkü güçlü sayaç == 1

    {
        std::weak_ptr<MyObject> weak_ptr2 = ptr1;
        // güçlü sayaç: 1, zayıf sayaç: 2
    } // weak_ptr2 kapsam dışına çıktı
    // güçlü sayaç: 1, zayıf sayaç: 1

} // ptr1 kapsam dışına çıktı
// güçlü sayaç: 0, zayıf sayaç: 1
// Nesne yok edildi, çünkü güçlü sayaç 0 oldu
// Kontrol bloğu, zayıf sayaç 0 olana kadar kalır