I have an object that many pointers point to. They often try to access the data. However at some point this object might be destroyed. How do I efficiently update those pointers as soon as I destroy the object so they won't point to unallocated memory and cause undefined behaviour?
My Idea was making a list of pointers that need to be updated to nullptr. This would be called in the destructor of the object. Ugly mess and a lot of work for every single thing that might be deallocated.
Maybe there is some use in those smart pointers for cases like these (never used them). How do C++ programmers handle stuff like that?
-
2en.cppreference.com/w/cpp/memory/weak_ptr, more particularly en.cppreference.com/w/cpp/memory/weak_ptr/expiredbipll– bipll2019年01月19日 16:22:32 +00:00Commented Jan 19, 2019 at 16:22
-
1How about reference counting?Psi– Psi2019年01月19日 16:42:22 +00:00Commented Jan 19, 2019 at 16:42
2 Answers 2
You simply need to use std::shared_ptr and std::weak_ptr.
shared_ptr are so smart that you won't need to delete them, they will get deleted when nobody references them anymore. Then, any weak_ptr related to this shared_ptr will sort of be informed and there's no risk for it to access unallocated memory.
When it needs it the weak_ptr will try to lock() and create a local shared_ptr. If the original shared_ptr was removed, lock() will fail to create the local shared_ptr and you will safely know the original pointer was deleted.
// Example program
#include <iostream>
#include <assert.h>
#include <memory>
int main()
{
std::shared_ptr<int> pI( new int(3) );
std::weak_ptr<int> wI( pI );
{
// check if weak_ptr still "points" to some valid data:
std::shared_ptr<int> pICopy = wI.lock();
assert( pICopy != NULL );
std::cout << "pI still valid " << *pICopy << std::endl;
}
pI.reset(); // this is equivalent to regular delete with shared_ptr
{
// check if weak_ptr does not "point" to any valid data:
std::shared_ptr<int> pICopy = wI.lock();
assert( pICopy == NULL );
std::cout << "pI not valid anyore" << std::endl;
}
}
1 Comment
Ugly mess and a lot of work for every single thing that might be deallocated
Well don't do the cleanup in the destructor. Make a separate function and call it in destructor .You can call this common cleanup function from the destructors of other objects.
Comments
Explore related questions
See similar questions with these tags.