Question about converting `void *` to `int` in C

  • A+
Category:Languages

I'm trying to pick my C skills again. I want to sum a sequence in different threads, each thread would return a pointer of the sum of a part of the sequence. However, when I tried to convert the void* type value local_sum to int, problem occurred.

I tried to convert with sum += *(int*)local_sum;, a segment error occurred and I got Process finished with exit code 11.

I found that if I use sum += (int)local_sum;, it would be okay. But I couldn't convince myself: shouldn't local_sum be a void *? Why it can be converted to int with (int)local_sum?

I'm so grateful it you could answer the problem.

The part that sum each process's return value is here:

int sum = 0; for (int i = 0; i < NUM_THREADS; i ++) {     void * local_sum;     pthread_join(count_threads[i], (&local_sum));     sum += (int)local_sum; } 

The function of a thread is here:

void * count_thr(void *arg) {     int terminal = ARRAY_SIZE / NUM_THREADS;     int sum = 0;     for (int i = 0; i < terminal; i ++) {         sum += *((int*)arg + i);     }     return (void*)sum; } 

 


You're returning the value of int sum by setting a void * address to it. In this case, the address is not valid. But, if you keep that in mind and get the value of sum by casting a void * to int it will work.

void * is used this way sometimes to return either a value (e.g. int) or an address to something (e.g. struct).

To illustrate this:

int a = 5; void *p = (void *)a; int b = (int)p; 

a, p, and b all have a value of 5. p does not point to a valid address. Trying to dereference p would result in undefined behavior:

b = *(int *)p; // Undefined Behavior! 

Consider the following program:

#include <limits.h> #include <stdio.h>  int main(void) {     int a, b;     void *p;      a = 5;     p = (void *)a;     b = (int)p;      printf("%d %p %d/n", a, p, b);      a = INT_MAX;     p = (void *)a + 1;     b = (int)p;      printf("%d %p %d/n", a, p, b);      return 0; } 

When compiled, I get the following warnings:

 $ gcc main.c -o main.exe main.c: In function ‘main’: main.c:9:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]      p = (void *)a;          ^ main.c:10:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]      b = (int)p;  ... 

A warning is issued because, as pointed out by @Gerhardh, the sizeof(int) and the sizeof(void *) may be different. You may suffer data loss if the value of the void * exceeds the maximum value a int can hold.

Output

 $ ./main.exe 5 0x5 5 2147483647 0x80000000 -2147483648 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: