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
}
CodePudding user response:
when I cast
int
tovoid*
...
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
}