I would like to know if the count of references in shared_ptr
becomes 1
.
In other words, I want to observe shared_ptr
.
It reminds me Observer pattern.
The whole picture is that there are several threads in the application requesting a logger instance. When each thread has done its job it deallocates its instance of shared_ptr
. Therefore, once all threads have completed, there is left a single instance of object and just one reference to the object - shared_ptr
. And the question is how to get rid of it. Evident solution is been rendered here: garbage collector running every 5 minutes...
Asked
Active
Viewed 85 times
0

Evg
- 25,259
- 5
- 41
- 83

alexander.sivak
- 4,352
- 3
- 18
- 27
-
1Why do you need to have an extra shared_ptr that you manually check? Can you let the last thread destroy the logger? – HolyBlackCat Jan 16 '22 at 09:19
-
2Could you describe, why one instance stays? Bug? By design? Why is it not deallocated with the last thread? That is the reason to use shared_ptr. Otherwise you would use a non-owning pointer. – Sebastian Jan 16 '22 at 09:25
-
there is a storage of loggers, instantiating and keeping shared pointers. You request a logger using getLogger, and it creates and keeps an instance of shared_ptr. Once you have completed, an instance of shared pointer is destroyed, and count of references is decremented. I want to check it periodically if the count of references is equal to 1. The only possibility is, probably, to create a thread functioning like a garbage collector. – alexander.sivak Jan 16 '22 at 09:27
-
2@alexander.sivak "and keeps an instance of shared_ptr": Why does it do that? It reads to me as if it should be storing a `std::weak_ptr`, not a `std::shared_ptr`. (But it isn't clear to me for what purpose the pointer is kept.) – user17732522 Jan 16 '22 at 09:31
-
1You can keep a weak_ptr in the storage, which does not count. But nor sure about the timing with multiple threads, when destroying a shared_ptr and generating a new one from the weak_ptr. Alternatively you can derive from shared_ptr and adapt the logic, when the last one is destroyed. – Sebastian Jan 16 '22 at 09:32
-
1@alexander.sivak To me, it feels like there is no benefit in "keeps an instance of shared_ptr". Why? Why add the overhead of managing the pointer by another thread? What would be the difference if the last thread destroyed the last instance of `shared_ptr`? – digito_evo Jan 16 '22 at 09:32
-
2@Sebastian Creating new `std::shared_ptr` from a `std::weak_ptr` is safe, even with multiple threads. Otherwise it wouldn't really be useful. (The `.lock()` method will simply return an empty `std::shared_ptr` if the object is already destroyed.) – user17732522 Jan 16 '22 at 09:34
-
1@Sebastian nice, I did not think of weak pointer before. – alexander.sivak Jan 16 '22 at 09:50
-
Don't try to do garbage collection in C++, what is your real problem? The need for observing shared_ptr seems like a design issue. – Pepijn Kramer Jan 16 '22 at 10:13
-
I think this might help you https://stackoverflow.com/questions/12321949/explicitly-deleting-a-shared-ptr – BitMask Jan 16 '22 at 10:21
-
The discussion about explicitly deleting a shared_ptr is interesting and can help, but I do not think there is a direct answer to this question. – Sebastian Jan 16 '22 at 10:53
-
As far as I understood, the main aim is to cache and reuse logging classes. As long as there are active ones, they can be shared by multiple threads. As soon as no thread uses it any more, it can be destroyed. And would be created anew for a next request. – Sebastian Jan 16 '22 at 10:56
-
Look at this example https://en.cppreference.com/w/cpp/memory/weak_ptr the lock() creates a shared_ptr copy (bad naming, you do not have to unlock). The else branch means, you were too slow and the logging object was destroyed 1 or 2 ns earlier, because the last threads using those terminated just at this time. – Sebastian Jan 16 '22 at 11:06
2 Answers
2
Therefore, once all theads have completed, there is left a single instance of object and just one reference to the object - shared_ptr. And the question is how to get rid of it.
Simply don't create the extra shared pointer to the object in the first place.

eerorika
- 232,697
- 12
- 197
- 326
-
But then threads shall hold different instances of objects - the logger instances. It does not satisfy my requirements. – alexander.sivak Jan 16 '22 at 09:31
-
@alexander.sivak you can make copies of shared pointers. They will point to the same instance. – eerorika Jan 16 '22 at 09:45
-
0
You can use std::shared_ptr::use_count or std::shared_ptr::unique in C++20:
#include <iostream>
#include <memory>
int main( )
{
auto sptr { std::make_shared<double>( 10.0 ) };
std::cout << "use count == " << sptr.use_count( )
<< " --- is unique? " << std::boolalpha << sptr.unique( ) << std::noboolalpha << '\n';
auto sptr2 { sptr };
std::cout << "use count == " << sptr2.use_count( )
<< " --- is unique? " << std::boolalpha << sptr2.unique( ) << '\n';
}
Sample output:
use count == 1 --- is unique? true
use count == 2 --- is unique? false

digito_evo
- 3,216
- 2
- 14
- 42
-
I understand I could make use of use_count method, but the question gets more general in a sense that how to think up an approach to the problem I described. – alexander.sivak Jan 16 '22 at 09:11
-
1@alexander.sivak Aha, but your question did not consist of those details at the beginning therefore I thought this could help. – digito_evo Jan 16 '22 at 09:21
-
@alexander.sivak `use_count()` wouldn't even be reliable when several threads are involved, see [cppreference](https://en.cppreference.com/w/cpp/memory/shared_ptr/use_count#Notes). – HolyBlackCat Jan 16 '22 at 09:22