1

クラッシュする次のコードがあります。これは、この問題があるスタックへの参照を割り当てているためだと思われます。しかし、毎回ミューテックスとスコープロックをスタック割り当てするコストを回避したい

 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; 


 }   

その後、関数が存在し (cache_lock はクラス フィールドです)、別のクラス メソッド内から cache_lock.lock を呼び出そうとすると、プログラムがクラッシュします (この場合、updateCache は cache_lock->lock() 部分でクラッシュします)。

2 つの質問があります。「永続的な」cache_lock を作成して、named_mutex (open_only など) を呼び出さずに再利用できるようにするにはどうすればよいですか? 毎回これを行うのは避けたい

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() ; 

}

次に、上記の手順を繰り返す (つまり、ミューテックスを見つけて、そこからロックを作成する) コストのかかる操作ですか?

4

1 に答える 1

3

ローカル変数へのポインタがあります。ローカル変数は、関数の実行中にのみスタックに存在し、関数が返されると、それらのオブジェクトは破棄され、それらのデストラクタが呼び出されます。これらのオブジェクトが占有していたメモリは、関数が返された後、次に呼び出される関数によって再利用されます。これは、あなたが持っているポインターが破壊された可能性のあるオブジェクトを指しているだけでなく、まったく別のものに使用されているメモリを指している可能性があることを意味します。もちろん参考書も同様です。

new代わりに、これらのオブジェクトをヒープに割り当てるか、スマート ポインターを使用します。


コンストラクター初期化子リストで、クラス内のオブジェクトの特定のコンストラクターを呼び出すことができます。

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_;

    // ...
};
于 2013-01-16T11:11:23.837 に答える