Timeline for answer to When is std::weak_ptr useful? by David Schwartz
Current License: CC BY-SA 3.0
Post Revisions
24 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Oct 28, 2020 at 22:09 | comment | added | David Schwartz | @Milan 1) The cache is part of memory. Keeping them in cache means keeping them in memory. 2) If we didn't have a weak pointer to the object, how would we find it if someone checked for it in the cache? It's in memory, we want the cache to be able to find it. 3) Not really, though you can look at the code. github.com/ripple/rippled/blob/develop/src/ripple/basics/… | |
| Oct 28, 2020 at 21:15 | comment | added | Milan | Thanks @DavidSchwartz for clarifying however I still have some more confusion/questions (sorry if they are stupid) 1. For recently accessed objects, we want to keep them in the cache rather than memory, right? 2. if some other application already has a strong pointe then why do we need weak_ptr? As another application has strong ptr to that object, the reference count won't be 0, right? 3. If you have good references for your answer that I can look into for an in-depth explanation then please do share. | |
| Oct 23, 2020 at 6:46 | comment | added | David Schwartz | @Milan The OS has no idea this cache exists, it's part of the application. A "strong pointer" is a pointer that represents ownership in the object and prevents it from being deleted. | |
| Oct 22, 2020 at 16:40 | comment | added | Milan | @DavidSchwartz, if possible, could you please elaborate on what did you mean by a strong pointer? Also, what did you mean by you scan the cache in "Periodically, you scan the cache and decide which objects have not been accessed recently. You don't need to keep those in memory, so you get rid of the strong pointer."? If I'm not wrong, OS scan the cache, right? | |
| Apr 18, 2020 at 17:48 | comment | added | Franky | I read your answer three times, but didn't understand what you accurately said. | |
| May 12, 2019 at 20:06 | comment | added | David Schwartz | @Oscar Typically a cache has a well-defined operation that finds an object in the cache and extends it life. Your scheme would work but would allow any access to the object at all to reset the life of the object in the cache. So it would produce results with different semantics. I agree that this is a pretty fine difference and likely both schemes would work just as well under most circumstances. | |
| Mar 4, 2019 at 9:15 | comment | added | Oscar | If something is still using it (holding another shared_ptr to it), I wouldn't remove it from the cache. It's in use... so why would you deem it "expired?" As you say, if it's still in memory, other code should be able to find it. On our next pruning trip through the cache, we'll see if everyone's done with it, and if so it will then be expired. | |
| Mar 4, 2019 at 1:53 | comment | added | David Schwartz |
@Oscar Say something is holding a shared_ptr to the object but it expires from the cache. What do you do? You don't want the cache to pin it in memory, so you can't keep a shared_ptr. But so long as the object is still in memory, you need to make sure code that checks the cache can find it. Other than having the cache hold a weak_ptr, what's your solution?
|
|
| Mar 3, 2019 at 6:23 | comment | added | Oscar | Thanks for your reply. If you're going to iterate through the cache periodically to check for agedness, it can check the reference count on a shared_ptr just as it would check the validity of a weak_ptr, right? If something is expiring from the cache, it's going to be removed whether its reference is a weak_ptr or a sole shared_ptr, right? I don't see why using a different pointer type causes a proliferation of "unlimited copies." If the object is re-created, it'll be added back to the cache and won't expire for a while, no? | |
| Mar 3, 2019 at 0:57 | comment | added | David Schwartz |
@Oscar How do you remove something from the cache without risking having an arbitrarily large number of copies of the item in memory then? If you keep the strong_ptr, the object never goes away. If you throw it away, then you can wind up with an unlimited number of copies of the object in memory as the next thread won't find it in the cache even if it's still in memory. Having the cache demote the strong_ptr to a weak_ptr solves the problem.
|
|
| Mar 2, 2019 at 22:58 | comment | added | Oscar | I still don't see why the cache should use weak_ptr over shared_ptr. Is it an issue of overhead? In either case, you have to maintain some kind of last-access-time list for all the objects if you're going to remove disused items periodically. So why choose one type of pointer over the other? | |
| Jan 22, 2019 at 16:38 | comment | added | David Schwartz | There's an implementation that does this in the source code for rippled. If the object expires from the cache but there are existing strong pointers, it is demoted to being cached by a weak pointer. This permits the object to be destroyed if it's not being used but also found (and re-cached) if requested prior to being destroyed. | |
| Jan 22, 2019 at 16:32 | comment | added | Helping Bean | @DavidSchwartz Could you clear up more on this? I couldn't get like when an object is not in the cache, how the new users of the cache can find the object in the cache and promote the weak pointer to strong pointer. | |
| Sep 26, 2018 at 17:43 | comment | added | David Schwartz | @rubenvb What happens if new users of the cache look for the object in the cache? They won't find it even though it's in memory. If an object is used for long enough, you could wind up with numerous copies of it in memory, defeating the purpose of the cache. With the weak pointer, new cache users can find the object and cause the weak pointer to be promoted to a strong pointer, putting the object back in the cache and avoiding having unlimited copies in memory. | |
| Aug 9, 2018 at 14:49 | comment | added | rubenvb | ...Unless you're using the presence of a resource some sort of cancellation signal... | |
| Aug 9, 2018 at 14:44 | comment | added | rubenvb | Wait, what is wrong with the cache holding a shared_ptr and just removing it from its list when it should be cleared from memory? Any users will hold a shared_ptr all the same and the cached resource will be cleared as soon as all users are done with it. | |
| Jul 3, 2018 at 18:47 | comment | added | curiousguy | @ShelbyMooreIII If you write a ref counted smart ptr without a weak ptr, you need a separate object to store the count, unless the count is allocated with the managed object. | |
| Jan 13, 2018 at 21:40 | comment | added | Shelby Moore III |
The cache use case could work with a shared reference if the cache was able to test if the refcount is 1, thus knowing it has the only reference and it could release it reclaiming on demand. This would eliminate the need for weak references in this case. Weak references require a separate object for the count which has some performance and space drawbacks (although afaik that's the way shared_ptr always works in C++ apparently, so no choice).
|
|
| Jan 26, 2017 at 17:38 | comment | added | Jason C | Another example, which I've used a few times at least, is when implementing observers, it sometimes becomes convenient to have the subject maintain a list of weak pointers and do its own list cleanup. It saves a little bit of effort explicitly removing observers when they are deleted, and more significantly you don't have to have information about the subjects available when destroying observers which generally simplifies things a lot. | |
| Sep 19, 2016 at 21:10 | comment | added | The Vivandiere | While a strong pointer keeps an object alive, a weak_ptr can look at it... without mucking with the object's life time. | |
| Aug 20, 2012 at 8:18 | vote | accept | Community Bot | ||
| Aug 19, 2012 at 23:38 | comment | added | David Schwartz | @R.M.: Basically, yes. When you have a weak pointer, you can attempt to promote it to a strong pointer. If that object still exists (because at least one strong pointer to it exists still) that operation succeeds and gives you a strong pointer to it. If that object does not exist (because all strong pointers went away), then that operation fails (and typically you react by throwing away the weak pointer). | |
| Aug 19, 2012 at 23:16 | comment | added | user1434698 | So std::wake_ptr can point only where another pointer points and it points to nullptr when the object pointed is deleted/not pointed by any other pointers anymore? | |
| Aug 19, 2012 at 23:06 | history | answered | David Schwartz | CC BY-SA 3.0 |