简体   繁体   中英

C++ dereference a void pointer , converting int ptr to void ptr

These lines of code show below error:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; 
cout << *vPtr; 

syntax error :

`void*' is not a pointer-to-object type

I know:

  1. any pointer type can be stored in void pointer type without explicit cast
  2. dereferencing attempt to void pointer is a syntax error

but if we can not do point # 2, what is the use of point # 1 except for being syntactically correct? I want to print 5 (ie e here) using vPtr ..is that possible?

This works fine:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; //specific to generic Ok!
double * dPtr = (double *)vPtr; //to let compiler know stoarge size
cout << *dPtr; //indirectly it is vPtr i.e. a void ptr, can be deref only if cast

To deference a void* pointer, you need to cast the pointer back to a compatible type.

void* pointers are frequently used in C, however, since in C++ we can do function overloading and polymorphism, their use is much more limited.

A good exemple of use of void* pointers in C are functions that use callbacks :

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                   void *(*start_routine) (void *), void *arg);

When you call the pthread_create function, it calls your start_routine back. In this case, you may want to pass some data to your start_routine . Since the thread library cannot declare a pthread_create function for every type you may want to pass to you callback, the void* type is used instead.

void myCallBack(void* arg) {
   int* value = (int*)arg;

   /* Do something with value: it is an int* now*/
   printf("Message from callback %d\n", *value);
}


/* Some main function or whatever... */
{ 
  /*  ... */
  int foo = 123;
  ret = pthread_create(&thread, &attr,myCallBack, &foo);

  /*  ... */
}

void* can point to anything, therefore assigning any pointer to it is perfectly fine.

But because it might point to anything, dereferencing it is not possible: The compiler does not know which object type it points to, so it is not able to generate code to do the right thing depending on the object's type.

You can't dereference it because the compiler doesn't know what it is. You have to cast it into an appropriate type (and the compiler has to assume you know what you are doing).

void * pointers are best used where you are interfacing with stuff at a fairly low level (such as I/O drivers) where you care very little what the data you are dealing with, you just know you have a buffer and a size.

Any other use is fraught with danger. For instance

int i = 5;
void *p = &i;
.....
float *f = (float *)p;

This will get no compiler errors or warnings. It's perfectly valid. But it is unlikely to do what you expect

It can be useful to store a pointer and remain indifferent to its type. This is what void* is for. It is one approach you can take when designing a storage container (linked list, hash map) in pure C.

If you wanted to make use of the pointer then you would have to track its type as well as its value, since you cannot arbitrarily deference pointers, and all type information is lost when you cast to void*.

In your example, you could use a simple structure with a void* and a type field.

In C++ you can achieve these things with polymorphic structures and even templates: what you are doing is far more C style.

You cannot print e here using void* without typecasting. A pointer is not just a simple variable which store the address, but it has got a type too which tells the compiler how much size it should read using that address. A void* , as it do not posses any type, cannot be dereferenced without typecasting. By typecasting, you tell the compiler how much bytes it should read starting from the address that pointer carries.

void* provides an easy way for the programmer to easily store and use pointers of other types. We cannot use unsigned int or similar to store the value of a pointer since the size of a pointer is dependent on the processor. Also, we can use void* to make pointer arguments/return value of functions more generic.

I thing so you want to store int pointer to void* pointer. In that condition you may get warning like "cast to pointer from integer of different size".For that you first need to assign some memory void pointer related to integer, and then use that void pointer may be like follow,

void *ptr = malloc(sizeof(int));
*((int*)ptr) = 5;
printf("%d\n",*((int*)ptr));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM