As you can see, when I cast int to void* and then cast it back to int, the value is not the same, and I encounter a segmentation fault. What is the problem with this? I also tried int j = *(int*)i and it fails, too.
void* run(void* i)
{
// some code
uintptr_t j = (intptr_t)(void*)i;
// some code
}
int main()
{
// some code
for (int i = 0; i < THREADS; i++)
{
void *pointer = &i;
pthread_create(&threads[i], NULL, run, pointer);
}
// some code
}
>Solution :
when I cast
inttovoid*…
You are not actually doing that. Your run() function is expecting you to cast the value of i to a void*, but your main() loop is instead assigning the address of i to a void*. Big difference.
The reason why int j = *(int*)i fails (although it is syntactically correct when using void *pointer = &i;) is because you are making all of the threads act on a single int variable in memory. That int is changing value on each loop iteration in main(), without telling the threads that it is changing. And worse, the lifetime of that int ends as soon as the loop ends, leaving each thread with a dangling pointer.
If you want each thread to act on its own int value, you need to pass around the value of i, not the address of i, eg:
void* run(void* arg)
{
// some code
int j = (int)(intptr_t)arg;
// some code
}
int main()
{
// some code
for (int i = 0; i < THREADS; i++)
{
void *pointer = (void*)(intptr_t)i;
pthread_create(&threads[i], NULL, run, pointer);
}
// some code
for (int i = 0; i < THREADS; i++)
pthread_join(&threads[i], NULL);
// some code
}
Alternatively, allocate a separate int for each thread, and then pass the address of each thread’s int, eg:
void* run(void* arg)
{
// some code
int j = *(int*)arg;
// some code
}
int main()
{
// some code
int arr[THREADS];
for (int i = 0; i < THREADS; i++)
{
arr[i] = i;
void *pointer = &arr[i];
pthread_create(&threads[i], NULL, run, pointer);
}
// some code
for (int i = 0; i < THREADS; i++)
pthread_join(&threads[i], NULL);
// some code
}