Hi I am reading through this document and some other documents about C++'s shared_ptr
and they all seem to suggest that apart from the number of shared_ptr
pointing to the allocated object, the reference count object has to keep track of how many weak_ptr
pointer pointing to the object as well. My question is why? From my understanding, weak_ptr
is non-owning so if the count of shared_ptr
pointing to the object reaches zero the object can be deleted. That is why sometimes we need to use expired to check the availability of an object pointed by a weak_ptr
. Could you explain the reason for needing to keep track of the number of weak_ptr
s?

- 6,963
- 10
- 39
- 72
-
7I believe it's because otherwise, the `weak_ptr` wouldn't be able to know if it was expired. You have the keep the block of memory alive so that the `weak_ptr`s know that the pointer has expired, but you also want to delete the memory after all the `weak_ptr`s are gone – Justin Jul 19 '17 at 20:02
-
@Justin I was like "Can't you just test wp1's pointer to the manager object is null" and then I realised "Ah, of course you cannot do that otherwise you solved the problem of deleting a ptr twice will seg fault your program issue." – Bob Fang Jul 19 '17 at 20:05
-
3Basically, the only other solution would be to keep a list of all `weak_ptr`s stored. Then, when the shared count gets to 0, you inform every `weak_ptr` that the memory was destroyed. This would be less efficient, especially in terms of memory used. – Justin Jul 19 '17 at 20:07
-
2As a sidenote, your graphic is misleading because the pointer to the managed object is stored inside each `shared_ptr`/`weak_ptr`. There may be another pointer inside the deleter (inside the control block aka manager object). This allows different pointer instances to have the same ownership relation but *different pointees*. – Arne Vogel Jul 20 '17 at 12:14
-
https://stackoverflow.com/a/14043328/412080 – Maxim Egorushkin Jul 25 '17 at 12:01
-
@Justin "_you inform every weak_ptr that the memory was destroyed_" creating the possibility of having some expired and other non expired weak ref to the same object, during a short time which could be extended indefinitely if some weak ref is turned into a strong ref! – curiousguy Aug 22 '17 at 04:18
3 Answers
std::weak_ptr
refers to the control block to know if the object still exists and if so, to provide a std::shared_ptr
to it when needed. For that reason, the control block must exist as long as either a std::weak_ptr
or a std::shared_ptr
exists. You need to track the number of instances of std::weak_ptr
to know when the last one is destroyed, just like for std::shared_ptr
.

- 28,148
- 6
- 56
- 87
-
2Right, if it weren't so, the control block would need to contain information about all `weak_ptr` instances so that they can be nulled out (in a thread-safe manner, no less) on expiry. It's much easier to let the `weak_ptr` perform polling on `lock()` instead. – Arne Vogel Jul 20 '17 at 12:15
The shared_ptr
reference count is the count of owners of the object. The weak_ptr
reference count is the count of owners of the reference count control block.

- 104,103
- 58
- 317
- 552
-
So, you are claiming a new shared pointer adds 1 to both values? – Yakk - Adam Nevraumont Jul 19 '17 at 20:13
-
3@Yakk: Yes, but good implementations make the population of shared_ptrs behave as one weak_ptr. – Billy ONeal Jul 19 '17 at 20:15
-
-
Adding to the answer by François Andrieux:
There is a side effect of this that is very important to understand.
If you use an implementation of std::make_shared that uses the WKWYL optimization (We Know Where You Live) of allocating the control block and the actual object together as one contiguous allocation, the memory WILL NOT BE FREED until after all weak_ptr objects have also gone out of scope.
(my account is seldom used, so I cannot add comments, due to not having enough reputation points, thus adding as an answer rather than a comment)

- 91
- 2