Home > Back-end >  change in value after casting int to uintptr_t
change in value after casting int to uintptr_t

Time:12-23

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 to void* ...

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
}
  • Related