Question

I have the following code which crashes. I suspect this is because of allocating a reference to the stack that I have this problem. But I want to avoid the cost of having to stack allocate a mutex, and a scoped lock every time

 class Cache { 
  public:
    void createCacheLock(const char* name) { 
       named_mutex mutex_(open_only, name);
       mutex = &mutex_;
       scoped_lock<named_mutex> cache_lock_(mutex_, defer_lock);
       cache_lock=&cache_lock_ ; 

   }

 void updateCache(const char* name, int newvalue) { 
             cache_lock->lock()  ; 
             /* Do update work */
             cache_lock->unlock() ; 
 }

 private: 
     named_mutex* mutex ;  
     scoped_lock<named_mutex>* cache_lock; 


 }   

I then exist the function (cache_lock is a class field), and when trying to call cache_lock.lock from within a different class method, my program crashes (in this case the updateCache crashes in the cache_lock->lock() part)

I have two questions: how can I create a "persistent" cache_lock, so that I can reuse it without the call to named_mutex (open_only, etc.)? ak I would like to avoid doing this every time

void updateCache(const char* name, int newvalue) { 
        named_mutex mutex_(open_only, name);
        scoped_lock<named_mutex> cache_lock_(mutex_, defer_lock);  
        /* Do update work */
         cache_lock->unlock() ; 

}

Secondly, repeating the procedure above (namely, finding the mutex, and creating a lock from it) an expensive operation?

Was it helpful?

Solution

You have pointers to local variables. Local variables exists on the stack only while the function runs, when the function returns those objects are destroyed and their destructors called. The memory those object occupied will after the function returns be reused by the next function to be called. This means that the pointers you have not only points to possibly destructed objects, the can also point to memory being used for something completely different. The same goes for references of course.

Allocate those objects on the heap with new instead, or use smart pointers.


You can call specific constructors of objects in your class in your constructors initializer list:

class cache
{
public:
    cache(const std::string& lock_name)
        : mutex_(open_only, lock_name),
          cache_lock_(mutex_, defer_lock)
        {}

    // ...

private:
    named_mutex mutex_;
    scoped_lock<named_mutex> cache_lock_;

    // ...
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top