Search code examples
winapimovestdvectorcritical-section

Can a critical section object be stored in a std::vector?


According to the documentation, a critical secion object cannot be copied or moved.

Does that imply it cannot be safely stored in a std::vector style collection as an instance?


Solution

  • Correct; the CRITICAL_SECTION object should not be copied/moved as it may stop working (E.g. perhaps it contains pointers to itself).

    One approach would be to store a vector of smart pointers, e.g. (C++17 code):

    #include <windows.h>
    #include <memory>
    #include <vector>
    
    using CS_ptr = std::unique_ptr<CRITICAL_SECTION, decltype(&DeleteCriticalSection)>;
    
    CS_ptr make_CriticalSection(void)
    {
        CS_ptr p(new CRITICAL_SECTION, DeleteCriticalSection);
        InitializeCriticalSection(p.get());
        return p;
    }
    
    int main()
    {
        std::vector<CS_ptr> vec;
        vec.push_back( make_CriticalSection() );    
    }
    

    Consider using std::recursive_mutex which is a drop-in replacement for CRITICAL SECTION (and probably just wraps it in a Windows implementation), and performs the correct initialization and release in its destructor.

    Standard mutexes are also non-copyable so for this case you'd use std::unique_ptr<std::recursive_mutex> if you wanted a vector of them.

    As discussed here also consider whether you actually want std::mutex instead of a recursive mutex.

    NOTE: Windows Mutex is an inter-process object; std::mutex and friends correspond to a CRITICAL_SECTION.


    I would also suggest reconsidering the need for a vector of mutexes; there may be a better solution to whatever you're trying to do.