Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 1 | # //base/memory Types |
| 2 | |
| 3 | ## Overview |
| 4 | This directory contains a variety of pointer-like objects (aka smart pointers). |
| 5 | This is a brief overview of what they are and how they should be used. Refer to |
| 6 | individual header files for details. C++ is not memory safe, so use these types |
| 7 | to help guard against potential memory bugs. |
| 8 | There are other pointer-like object types implemented elsewhere that may be |
David Benjamin | 1d737482 | 2024-07-09 19:54:35 | [diff] [blame] | 9 | right for a given use case, such as `std::optional<T>` and |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 10 | `std::unique_ptr<T>`. More on all types in video form |
| 11 | [here](https://youtu.be/MpwbWSEDfjM?t=582s) and in a doc |
| 12 | [here](https://docs.google.com/document/d/1VRevv8JhlP4I8fIlvf87IrW2IRjE0PbkSfIcI6-UbJo/edit?usp=sharing). |
| 13 | |
| 14 | ## `raw_ptr<T>` |
Kalvin Lee | d831054f | 2022-11-24 12:21:29 | [diff] [blame] | 15 | Use for class fields/members that would otherwise be a `T*`. |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 16 | |
Kalvin Lee | d831054f | 2022-11-24 12:21:29 | [diff] [blame] | 17 | This is a weakly refcounted wrapper for a `T*` (also called a raw |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 18 | pointer). When the object is deleted, the allocator will "poison" the memory |
| 19 | that object occupied and keep the memory around so it’s not reused. This reduces |
| 20 | the risk and impact of a use-after-free bug. |
| 21 | |
| 22 | Depending on the use case, it's possible a smart pointer with additional |
| 23 | features would be more appropriate, but if none of those are applicable or |
Kalvin Lee | d831054f | 2022-11-24 12:21:29 | [diff] [blame] | 24 | necessary, `raw_ptr<T>` is preferred over a `T*`. |
| 25 | |
| 26 | For more information, see [`raw_ptr.md`](./raw_ptr.md); for guidance on |
| 27 | usage, see |
| 28 | [the style guide](../../styleguide/c++/c++.md#non_owning-pointers-in-class-fields). |
| 29 | |
| 30 | ## `raw_ref<T>` |
| 31 | Use for class fields/members that would otherwise be a `T&`. |
| 32 | |
| 33 | This shares much in common with `raw_ptr<T>`, but asserts that the |
| 34 | `raw_ref<T>` is not nullable. |
| 35 | |
| 36 | For more information, see [`raw_ptr.md`](./raw_ptr.md); for guidance on |
| 37 | usage, see |
| 38 | [the style guide](../../styleguide/c++/c++.md#non_owning-pointers-in-class-fields). |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 39 | |
| 40 | ## `base::WeakPtr<T>` |
| 41 | Use when a reference to an object might outlive the object itself. |
| 42 | |
| 43 | These are useful for asynchronous work, which is common in Chrome. If an async |
| 44 | task references other objects or state, and it's possible for that state to be |
| 45 | destroyed before the task runs, those references should be held in a |
| 46 | `WeakPtr<T>`. Each `WeakPtr<T>` is associated with a `WeakPtrFactory<T>`. When |
| 47 | the associated factory (usually owned by T) is destroyed, all `WeakPtr<T>` are |
| 48 | invalidated (becomes null) rather than becoming use-after-frees. If such |
| 49 | references should never outlive the object, consider using SafeRef instead. |
| 50 | |
| 51 | ## `base::SafeRef<T>` |
| 52 | Use to express that a reference to an object must not outlive the object. |
| 53 | |
| 54 | An example is if you have a class member that you want to guarantee outlives the |
| 55 | class itself. SafeRef automatically enforces the lifetime assumptions and |
| 56 | eliminates the need for validity checks. |
| 57 | |
| 58 | If the assumption that the object is valid is broken, then the process |
| 59 | terminates safely and generates a crash report. Though not ideal, it's |
| 60 | preferable to a potentially undiscovered security bug. |
| 61 | |
| 62 | This type is built on top of WeakPtr, so if you want a `SafeRef<T>`, T needs a |
| 63 | WeakPtrFactory as a member. It works like `WeakPtr`, but doesn't allow for a |
| 64 | null state. There's also overlap with `raw_ptr`, though this was implemented |
| 65 | first. |
| 66 | |
Hong Xu | 77f05a2 | 2023-11-08 22:51:58 | [diff] [blame] | 67 | ## `scoped_refptr<T>` |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 68 | Use when you want manually managed strong refcounting. Use carefully! |
| 69 | |
| 70 | It’s an owning smart pointer, so it owns a pointer to something allocated in the |
| 71 | heap and gives shared ownership of the underlying object, since it can be |
Hong Xu | 77f05a2 | 2023-11-08 22:51:58 | [diff] [blame] | 72 | copied. When all `scoped_refptr<T>`s pointing to the same object are gone, that |
Sharon Yang | 438462e | 2022-08-25 19:51:07 | [diff] [blame] | 73 | object gets destroyed. |
| 74 | |
| 75 | This is Chrome's answer to `std::shared_ptr<T>`. It additionally requires T to |
| 76 | inherit from `RefCounted` or `RefCountedThreadSafe`, since the ref counting |
Hong Xu | 77f05a2 | 2023-11-08 22:51:58 | [diff] [blame] | 77 | happens in the object itself, unlike `shared_ptr<T>`. |
| 78 | |
| 79 | It's preferred for an object to remain on the same thread, as `RefCounted` is |
| 80 | much cheaper. If there are `scoped_refptr<T>`s to the same object on different |
| 81 | threads, use `RefCountedThreadSafe`, since accesses to the reference count can |
| 82 | race. In this case, without external synchronization, the destructor of |
| 83 | `scoped_refptr<T>`, which decreases the reference count by one, can run on any |
| 84 | thread. |
| 85 | |
| 86 | Inheriting from `RefCountedThreadSafe` by itself doesn't make a class `T` or the |
| 87 | underlying object of `scoped_refptr<T>` thread-safe: It merely ensures that the |
| 88 | counter manipulated by `scoped_refptr<T>` is thread-safe. |
| 89 | |
| 90 | If the destructor interacts with other systems it is important to |
Sharon Yang | ab24b2a | 2022-09-06 19:36:48 | [diff] [blame] | 91 | control and know which thread has the last reference to the object, or you can |
| 92 | end up with flakiness. |