I have a library with APIs using std::shared_ptr
as arguments.
I would like to use these APIs together with pthreads.
What I'm doing is: getting a raw pointer from the shared_ptr, in order to pass it to the pthread.
Create a new shared_ptr from the raw one and call my API from another thread.
However I get a double free or corruption
error when converting the raw pointer back to a shared one.
This is my code
#include <memory>
#include <iostream>
#include <thread>
#include <pthread.h>
void* print_task(void* ptr)
{
int* val_raw = static_cast<int*>(ptr);
std::shared_ptr<int> val(val_raw);
// CALL MY API WHICH TAKES A SHARED_PTR AS ARGUMENT
std::cout<<"thread job done \n";
}
int main(int argc, char ** argv)
{
pthread_t thread;
std::shared_ptr<int> val = std::make_shared<int>(10);
pthread_create(&thread, nullptr, &print_task, static_cast<void *>(val.get()));
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
I guess that I'm doing something wrong with all the conversions from shared to raw pointer, because the same code using std::threads (where I can pass directly a shared_ptr) works. However I need to set thread priorities, thus I'm trying to do this with pthreads.
Do you know how to change my code in order to be able to pass a shared pointer and use it inside a pthread?
As mentioned in the comments already, the problem is passing a shared pointer through a raw void pointer, so I'll ignore the threading part for now:
// this is what we have and what we want to pass to the given function
shared_ptr<some_type> sptr;
// function to somehow pass the shared pointer to
void function(void* ptr);
// As always, when passing anything that doesn't fit into
// the raw pointer, we need to do dynamic allocation:
void* arg = new shared_ptr<some_type>(sptr);
// we can now pass this to the function as intended:
function(arg);
// Note that we give up ownership of the dynamically allocated
// shared pointer instance. Hence, the called function must
// release that object again (it takes ownership). The function
// therefore starts like this:
void function(void* ptr)
{
// convert the typeless pointer to a typed pointer again
shared_ptr<some_type>* psptr = static_cast<shared_ptr<some_type>*>(ptr);
// move the content to a new, local instance
shared_ptr<some_type> sptr = *psptr;
// release the dynamically allocated shared pointer again
delete psptr;
/// ... code using sptr here ...
}
Now, while this is guaranteed to work, under some circumstances this may not be an optimal solution: