3

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?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Nicholas
  • 1,392
  • 16
  • 38
  • I'm guessing this is not a C++ class? if it were it should have its copy/move ctors explicitly deleted. – Brad Allred Jun 10 '19 at 22:35
  • 1
    sounds similar to a `std::mutex` (non-copyable and non-moveable) and an answer [here](https://stackoverflow.com/a/16466170/2189130) indicates yes you *can* but you can't do anything that would potentially resize the vector (meaning you can only construct it with a fixed size) – kmdreko Jun 10 '19 at 22:35
  • 2
    also, `unique_ptr` might be an option to store references to these safely inside a `std::vector` – Brad Allred Jun 10 '19 at 22:38
  • however, windows api structures are typically just declared as PODs which means you won't get a compiler error if you attempt to copy or move it :/ – kmdreko Jun 10 '19 at 22:41
  • @BradAllred it's part of a C API – M.M Jun 11 '19 at 00:25
  • i be first ask - what sense at all store it in `std::vector` ? – RbMm Jun 11 '19 at 00:54

1 Answers1

1

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.

M.M
  • 138,810
  • 21
  • 208
  • 365