Especially in older C++ programms it was very common to work with a lot of raw pointer (legacy pointer). That led to plenty of different memory issues, like accessing already deallocated memory and not deallocating memory at all. The first problem happens if you aren’t checking for a nullptr and then accessing already overwritten memory. Even the check can give a false positive if you haven’t explicitly set the raw pointer to a nullptr after deallocating the memory. The second problem happens if no one feels responsible for the raw pointer based on an unknown ownership. To decrease this issues raw pointer have been moslty mostly replaced by smart pointer these days. Shared pointers are wrapping raw pointers and adding some specific logic.
Unique pointer take the exclusive ownership of a resource. That resource will be destroyed as soon as the single owner releases its ownership.
// Creation std::unique_ptr<Foo> uPtr1(new Foo()); // since C++11 // auto uPtr1 = std::make_unique<Foo>(); // since C++14 // Move ownership std::unique_ptr<Foo> uPtr2 = std::move(uPtr1); // uPtr1 is nullptr // Manual destruction uPtr2.reset(); // uPtr2 is nullptr + rawPtr is deleted
Shared pointer share the ownership of a resource with others. A reference counter shows the amount of owning references. Just if that counter gets zero the resource gets destroyed.
// Creation std::shared_ptr<Foo> sPtr1(new Foo()); // since c++11 // auto sPtr1 = std::make_shared<Foo>(); // since c++11 // Share ownership std::shared_ptr<Foo> sPtr2 = sPtr1; // Manual destruction sPtr1.reset(); // sPtr1 is nullptr sPtr2.reset(); // sPtr2 is nullptr + rawPtr is deleted
Weak pointer pointing on a shared pointer and not directly to the resource. Just if they want access the resource they got a share pointer, else they have a non-owning reference.
// Creation std::shared_ptr<Foo> sPtr(new Foo()); // Get non-owning reference std::weak_ptr<Foo> wPtr = sPtr; // Get temp. owning reference { std::shared_ptr<Foo> tmpSPtr = wPTr.lock(); } // Manual destruction sPtr.reset(); // sPtr is nullptr + rawPtr is deleted + wPtr is expired
In the case of Java and C# their VM provides a garbage collector to handle the memory management on the heap automatically. Occuring problems with that strategy is the loss of performance at unspecific moments and a helplessness in the case that the garbage collector isn’t working correctly.