-2

When going through some of the links about void pointers, I have seen two types when setting and getting values from void pointers,

int main() {
    int i = 5;

    //This is first way.

    void *vPtr = (void *) i;

    //printing value of *vPtr,
    printf("Getting value in first way, %d\n", (int)vPtr);

    //This is second way.
    *vPtr = &i;

    //printing in second way,
    printf("Getting value in second way, %d\n", *((int*)vPtr));
}

Both of them will give the same value. Though I had an idea of how second method works, but I am not entirely sure, how first method works. What would be the ideal way when dealing with void pointers among these two?

For first method, this is the code snippet I was referring. Though he was passing long type, I could do the same with int also.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0;t<NUM_THREADS;t++){
     printf("In main: creating thread %ld\n", t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc){
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1);
       }
     }

   /* Last thing that main() should do */
   pthread_exit(NULL);
}
Kiran
  • 747
  • 2
  • 10
  • 35
  • 2
    Do not convert a pointer to an `int`! To print a pointer value use the correct format specifier `%p`. Please read about pointer operation, type coversion, etc. you are doing some very strange (and wrong) things. – too honest for this site Nov 15 '15 at 12:09
  • Hi @Olaf, I have added the code snippet from where first method was used to set and get values from void pointers. – Kiran Nov 15 '15 at 12:18

2 Answers2

0

The first way uses the pointer as a storage space for your integer; the second way stores the integer separately, and uses void* pointer to point to it.

Pointers are capable of holding memory addresses. Since memory addresses are essentially numeric values, pointers are capable of storing numbers. The range of such numbers, however, is system-dependent. For example, you can re-interpret a pointer as an integer number by passing it to printf with a %p format specifier. The numeric value produced by printf is system-defined, but you will get some number printed for your pointer.

The second approach is guaranteed to work. Moreover, if you change i, the value seen by the thread will change as well.

This implies that the value pointed to by the pointer must stay around for the duration when the thread could access it. This implies that if you were to change your threading code to use the second approach, a single t would not be sufficient; you would have to make an array of NUM_THREADS elements, and pass each thread an address to a different element.

The second approach will probably work on most hardware, because int usually fits into a space of a pointer. However, C99 standard does not make guarantees about it. Once you make an assignment, changes to i have no effect on the integer value seen by the thread.

You can find more information on the topic of converting an int to void* in this Q&A.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0
void *vPtr = (void *) i;

This interprets i as a pointer to something. In your example, vPtr would now point to address 0x00000005.

 *vPtr = &i;

This takes the address of i.

It all depends on what you want to do.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41