selim anac
selim anac

Reputation: 41

void* to array in C++ for thread

I'm using this thread lib(nothing special).

Is it possible to cast void* to string array in thread function?

#define  THREAD_IMPLEMENTATION
#include "thread.h"

#include <stdio.h> // for printf

int thread_proc( void* user_data)
{

    //Cast user_data to string array here

    return 0;
}

int main( int argc, char** argv )
{
    std::string foo[1] = {"Hello from array"};

    thread_ptr_t thread = thread_create( thread_proc, &foo, "Example thread", THREAD_STACK_SIZE_DEFAULT );
    return 0;
}

Upvotes: 2

Views: 490

Answers (2)

eerorika
eerorika

Reputation: 238441

Is it possible to cast void* to string array in thread function?

It is not possible. But you can convert void* to a pointer to anything as long as that void pointer points to an object of that type.

In your case, you've initialized the void pointer to point to std::string foo[1]. So, you can convert it back:

auto ptr_to_foo = static_cast<std::string (*)[1]>(user_data); // same as &foo

You can then indirect the pointer:

auto& foo_ref = *ptr_to_foo;
std::cout << foo_ref[0];

You need to be very diligent though, because if you convert the void pointer to a type other than the pointed object, the behaviour will be undefined.

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409442

Three things you need to remember:

  1. When you get a pointer to the array, it's really a pointer to the array itself. In your example, the type of &foo is std::string (*)[1].

  2. When you use arrays when a pointer is expected, it will naturally decay to a pointer to its first element. That is, if you use plain foo then it will be translated into &foo[0], and will be of type std::string*.

  3. When doing threads in C++ I really recommend std::thread instead of native C-based thread functions.

Also please try to use std::vector or std::array instead of C-style arrays.


For a C++-specific solution, it could instead look something like this

#include <array>
#include <string>
#include <thread>
#include <functional>  // For std::cref, see https://en.cppreference.com/w/cpp/utility/functional/ref

void thread_proc(std::array<std::string, 1> const& strings)
{
    // Use the (constant) array as you please here...
}

int main()
{
    std::array<std::string, 1> foo = { "Hello from array" };

    std::thread thread(&thread_proc, std::cref(foo));

    // Do things here...

    thread.join();
}

No casting needed. The only thing is that references needs to be passed using std::ref or std::cref when creating the thread object (because the arguments need to be copied, and references can't be copied).

Upvotes: 10

Related Questions