Sometimes some object A needs to interact with another object B, e.g., A calls one of B’s methods. In a language like C++, it is left to the programmer to assure that B outlives A; if B happens to be already destructed, this would be a use-after-free bug. Managing object lifetimes can be tricky, especially with asynchronous code.
A safe pointer in C++ that protects against use after free and updates when the pointee is moved
by Niek J. Bouman
From the article:
We propose a design for a safe pointer to an object of type T that is weak in that it does not have ownership semantics, and gets notified in case the pointee is either destructed or moved.
We will pay a price at runtime for these extra guarantees in terms of a small heap-allocated state, a double pointer indirection when accessing the pointee (comparable to a virtual function call), and a check against nullptr.
The main idea of our design is to internally use a
std::shared_ptr<T*>
to share ownership of a (heap-allocated) pointer T*. The ownership is shared by the pointee and allsafe_ptr<T>
instances. The pointee type T must derive from the base classsafe_ptr_factory
(templated on T, using the Curiously Recurring Template Pattern) with a destructor that automatically notifies the shared state about destruction by setting T* tonullptr
, and with a move constructor and move assignment operator that update T* to the new this pointer (which we must properly cast withstatic_cast<T*>
). The double indirection thus comes from having to dereference theshared_ptr
to obtain an ordinary pointer T*, after which you must dereference once more to access the pointee. You might recognize an instance of Gang-of-Four’s observer pattern in our design.
Add a Comment