I have a vector of pointers to objects created with new. Multiple threads access this vector in a safe manner with various gets/sets. However, a thread may delete one of the objects, in which case another thread's pointer to the object is no longer valid. How can a method know if the pointer is valid? Options 1 and 2 actually seem to work well. I don't know how they will scale. What is the best approach? Is there a portable version 3?
Testing for pointer validity examples that work:
1. Use integers instead of pointers. A hash (std::map) checks to see if the pointer is still valid. Public methods look like:
get(size_t iKey)
{
if((it = mMap.find(iKey)) != mMap.end())
{
TMyType * pMyType = it->second;
// do something with pMyType
}
}
2. Have a vector of shared_ptr. Each thread tries to call lock() on its weak_ptr. If the returned shared_ptr is null we know someone deleted it while we were waiting. Public methods looks like:
get(boost::weak_ptr<TMyType> pMyType)
{
boost::shared_ptr<TMyType> pGOOD = pMyType.lock();
if (pGOOD != NULL)
{
// Do something with pGOOD
}
}
3. Test for null on plain raw pointers? Is this possible?
get(TMyType * pMyType)
{
if(pMyType != NULL){ //do something }
}
#3 will not work. Deleting a pointer and setting it to NULL doesn't affect other pointers that are pointing to the same object. There is nothing you can do with raw pointers to detect if the object is deleted.
#1 is effectively a pointer to a pointer. If you always access it through that pointer and are able to lock it. If not, what happens if it's deleted in another thread after you successfully get it?
#2 is the standard implementation of this kind of idea, and the pattern is used in many libraries. Lock a handle, getting a pointer. If you get it, use it. If not, it's gone.