Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ shared_ptr from char* to void*

I am trying to pass a char * string to a function which will execute inside a thread. The function has the following prototype:

void f(void *ptr);

The thread allocation is made by a function similar to the following:

void append_task(std::function<void(void *)> &f, void *data);

I want to allocate a string that will be used inside the thread. Right Now I have this:

string name = "random string";
char *str = new char[name.length()];
strcpy(str, name.c_str());
append_task(f, static_cast<void *>(str));

I would like to discard the obligation to allocate and deallocate memory manually . How can I do this with std::shared_ptr (namely, the cast to void, and do I guarantee that the string is deallocated when the thread ends?)

P.S. Changing the append_task() function IS an option.

like image 747
manatttta Avatar asked Dec 24 '22 23:12

manatttta


2 Answers

First, ditch the second argument to append_task, and make it take a function with no arguments. Then pass the function by value, not reference. That way, you can just bind the extra data within a lambda, and count on std::string and std::function to do the memory management.

Like so:

void f(void *ptr);
void append_task(std::function<void()> f);

int main()
{
    std::string name = "random string";
    append_task( [=]{f((void*)name.c_str());} );
}
like image 186
Sneftel Avatar answered Jan 05 '23 00:01

Sneftel


Firstly there is a dangerous bug in your code:

char *str = new char[name.length()];
strcpy(str, name.c_str());

std::string::length returns the size of the string in bytes excluding the null byte at the end of the string. Then you copy into this buffer with strcpy which reads from a const char * until it hits a null byte into your buffer which is now too short to contain the null byte. You then pass this const char * into a function which now has no idea how long this array is and is probably assuming it to be a null terminated array. This kind of mistake is so common in C that you really need to avoid directly handling C-style strings as much as humanly possible.

As to how to solve your problem I can't improve on the solution using lambdas that Sneftel provides.

like image 35
sjdowling Avatar answered Jan 05 '23 00:01

sjdowling