Am I making a mistake, or is the solution checker too strict?
I\'ve read other solutions, and I can make them work well enough. But I wanted to try some different approaches:\n\n1. Use C++17\'s std::scoped_lock, which prev
I\'ve read other solutions, and I can make them work well enough. But I wanted to try some different approaches:\n\n1. Use C++17\'s `std::scoped_lock`, which prevents deadlocks for you (presumably by acquiring mutexes in predetermined total order).\n2. Bundle the locking / unlocking of a mutex to the calling of the corresponding `pick` / `put` function.\n\nNeither is working reliably. I will either get an incorrect answer (according to LeetCode) or I\'ll get a `heap-use-after-free` or `attempting double-free` error from the address sanitizer. Why?\n\nI suspect the solution checker is assuming a certain type of behavior and is not letting other behaviors pass, even if correct. Or am I making a mistake?\n\n```C++\nclass DiningPhilosophers {\npublic:\n  void wantsToEat(int philosopher,\n                  function<void()> pickLeftFork,\n                  function<void()> pickRightFork,\n                  function<void()> eat,\n                  function<void()> putLeftFork,\n                  function<void()> putRightFork) {\n    std::scoped_lock(forks[philosopher], forks[(philosopher + 1) % 5]);\n    \n    pickLeftFork();\n    pickRightFork();\n    eat();\n    putLeftFork();\n    putRightFork();\n  }\n\nprivate:\n  std::array<std::mutex, 5> forks;\n};\n```\n\n```C++\nclass DiningPhilosophers {\npublic:\n  void wantsToEat(int philosopher,\n                  function<void()> pickLeftFork,\n                  function<void()> pickRightFork,\n                  function<void()> eat,\n                  function<void()> putLeftFork,\n                  function<void()> putRightFork) {\n    Fork leftFork  = {philosopher,           pickLeftFork,  putLeftFork };\n    Fork rightFork = {(philosopher + 1) % 5, pickRightFork, putRightFork};\n    \n    if (philosopher == 0)\n      swap(leftFork, rightFork);\n    \n    with(leftFork, [&](){\n      with(rightFork, [&](){\n        eat();\n      });\n    });\n  }\n\nprivate:\n  struct Fork {\n    int index;\n    function<void()> pick;\n    function<void()> put;\n  };\n  \n  std::array<std::mutex, 5> forkMutexes;\n  \n  void with(Fork fork, function<void()> action) {\n    std::unique_lock lock(forkMutexes[fork.index]);\n    fork.pick();\n    action();\n    fork.put();\n  }\n};\n```
[]