0

I need to create a mutex inside the body of a thread dynamically and map it to a structure so that other threads can use it.

What I'm doing is

pthread_mutex_t* p = new pthread_mutex_t;
*p = PTHREAD_MUTEX_INITIALIZER;

Then, when all threads are done with the mutex, I run

pthread_mutex_destroy(p);

Now, this works fine. However, if I also attempt to

delete p;

after the destroy call, I get SIGSEGV signals every time.

My questions are:

  1. Is it ok to initialize the dynamically allocated mutex this way, can it lead to UB? Should I use pthread_mutex_init instead of the 'flag'?
  2. Is pthread_mutex_destroy enough in the case of this dynamically allocated mutex or should I delete it instead, in order to avoid memory leaks? Doing both seems to be an issue.

Also I know I'm mixing the C API with C++ in this case, but I kinda have to do it right now.

Thanks in advance.

pol
  • 173
  • 8
  • 1
    "*I get SIGSEGV signals every time*". From where? Maybe some other thread is still holding onto a reference? It's kind of important to find out. Run the program in a debugger and post the crash stack trace. Also please provide a complete [mre]. – kaylum Jun 02 '22 at 22:55
  • 3
    Everything that's `new`ed needs to be `delete`d, otherwise there's a memory leak. The End. If this results in a crash, the crash has nothing to do with the `new` and the `delete`, but due to some other bug in the code. – Sam Varshavchik Jun 02 '22 at 22:58
  • 2
    Should answer point 1 of your question: [PTHREAD_MUTEX_INITIALIZER vs pthread_mutex_init ( &mutex, param)](https://stackoverflow.com/questions/14320041/pthread-mutex-initializer-vs-pthread-mutex-init-mutex-param) `pthread_mutex_t* p = new pthread_mutex_t;` is not `static` – user4581301 Jun 02 '22 at 22:58
  • 1
    pre-c++11? If not, suggest you use `std::thread`, `std::mutex`, smart pointers, etc – yano Jun 02 '22 at 23:03
  • 3
    Suggestion: You're stuck using pthread primitives. Sucks sometimes, but that's life. When I'm forced to do this I find it still helps to wrap the pthread-guts in [RAII-observant](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) classes. `shared_ptr` if you got 'em. – user4581301 Jun 02 '22 at 23:05
  • 2
    Possibly useful: https://stackoverflow.com/questions/6883032/do-i-need-to-use-delete-after-pthread-mutex-destroy – Chris Jun 02 '22 at 23:07
  • 2
    Regarding your code, you're misusing what is clearly specifier as an *initializer* (hence the name). The correct syntax would be `pthread_mutex_t *p = new pthread_mutex_t(PTHREAD_MUTEX_INITIALIZER);` Regarding destroying it, so long as no thread, including the current thread, has the mutex locked, it can be destroyed using `pthread_mutex_destroy`, which leave it in an "uninitialized" state. Firing `delete` thereafter is your business, but obviously required unless you're fond of memory leaks. *Debug your code* to locate the sigsev. – WhozCraig Jun 02 '22 at 23:07
  • @kaylum I can no longer reproduce the issue with the debugger running, I assume it's indeed due to a race condition situation and the debugger somehow slows it down. I will edit the post when I manage to produce the stack trace. Also regarding the C tag, I added it because the pthread_mutex is theoretically C API but I removed it now. – pol Jun 02 '22 at 23:10
  • 1
    I ended up finding out what the problem was. I was accidentally calling unlock on the mutex much later when it was already deleted. Thanks for the help and sorry for the confusion. – pol Jun 02 '22 at 23:15

0 Answers0