std::shared_ptr in C++

Understanding std::shared_ptr

std::shared_ptr is a smart pointer that provides shared ownership of dynamically allocated objects. Unlike std::unique_ptr, which enforces exclusive ownership, std::shared_ptr instances to share ownership of the same resource. It employs a reference counting mechanism to keep track of the number of std::shared_ptr instances pointing to a particular object automatically deallocates the memory when the last shared pointer goes out of scope.

Syntax and Features

Declaration and Initialization:

#include <memory>

std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);

The std::make_shared function is preferred for creating a std::shared_ptr as it ensures both memory allocation and the creation of the managed object occur together, enhancing performance.

Features

1 Shared Ownership:

std::shared_ptr allows multiple pointers to share ownership of the same dynamically allocated object. Each std::shared_ptr instance maintains a reference count, and the object is automatically deallocated when the last shared pointer pointing to it goes out of scope.

std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
std::shared_ptr<int> ptr2 = ptr1; // Shared ownership

Multiple std::shared_ptr instances can share ownership of the same resource, leading to automatic memory management when the last owner releases the resource.

Example:

#include <memory>
#include <iostream>

int main() {
    // Creating a shared_ptr to manage dynamically allocated memory
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1; // Shared ownership

    // Accessing the managed object through ptr2
    std::cout << *ptr2 << std::endl; // Output: 42

    // No need to explicitly delete memory, handled by shared_ptr

    return 0;
}

2 Reference Counting

std::shared_ptr uses reference counting to keep track of the number of shared pointers pointing to the same object. When a shared pointer is copied or destroyed, the reference count is updated accordingly.

Example:

#include <memory>
#include <iostream>

int main() {
    // Creating a shared_ptr to manage dynamically allocated memory
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1; // Shared ownership

    // Displaying the reference count
    std::cout << "Reference count: " << ptr1.use_count() << std::endl; // Output: 2

    return 0;
}

3 Automatic Memory Management

std::shared_ptr automatically deallocates the associated memory when the last shared pointer pointing to the object goes out of scope. This ensures proper cleanup and prevents memory leaks.

Example:

#include <memory>
#include <iostream>

void func() {
    std::shared_ptr<int> ptr = std::make_shared<int>(42);
} // ptr goes out of scope and memory is automatically deallocated

int main() {
    func(); // Memory deallocated after func() returns
    std::cout << "Memory deallocated successfully" << std::endl;

    return 0;
}

4 Control Block

std::shared_ptr uses a control block to store the reference count and manage shared ownership of the object. Each std::shared_ptr instance points to the control block, which in turn points to the dynamically allocated object.

Example:

#include <memory>
#include <iostream>

int main() {
    // Creating a shared_ptr to manage dynamically allocated memory
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1; // Shared ownership

    // Displaying the address of the control block
    std::cout << "Control block address: " << ptr1.get() << std::endl;

    return 0;
}
// Output
Control block address: 0x131a2c0

Usage

#include <memory>

int main() {
    // Creating a shared_ptr to manage dynamically allocated memory
    std::shared_ptr<int> ptr = std::make_shared<int>(42);

    // Accessing the managed object
    *ptr = 100;

    // No need to explicitly delete the memory, handled by shared_ptr

    return 0;
}

In this example, the std::shared_ptr instance ptr manages the dynamically allocated integer object. When ptr goes out of scope, the associated memory is automatically deallocated if no other shared pointers are pointing to the object.