dereferencing void pointers

Started by
9 comments, last by ari556655 14 years, 1 month ago
I'm trying to do something like this int num = 21; void *vp = &num *vp = 12; //where the value of num should now equal 12, right? However, the compiler(xcode) does not allow me to do *vp = 12; I get one warning: "warning: dereferencing 'void *' pointer and one error, "error: invalid use of void expression". Any ideas?
Advertisement
Dereferencing a void pointer has no meaning. A void * is a pointer to something that you don't know the type of. If you want to do something meaningful with the pointer you need to cast it to a non-void * type.
Quote:Original post by SiCrane
Dereferencing a void pointer has no meaning. A void * is a pointer to something that you don't know the type of. If you want to do something meaningful with the pointer you need to cast it to a non-void * type.


How would I do that correctly?
See the void pointers section here.
"All you have to decide is what to do with the time that is given to you." - Gandalf
In this case you just wouldn't use a void * at all. You want to treat it as a pointer to an int so just use an int * to begin with.
I think I understand but am still slightly unclear on one issue. So what I'm actually trying to do is something like this:

typedef sruct{     void *data_ptr;     int data_type;   //flags indicating what kind of data it is: INT_TYPE, FLOAT_TYPE, etc...     BOOL active;}data_t;data_t data_list[N];BOOL register_data( int i, void* ptr, int data_type ){       if ( ! data_list.active) {             data_list.data_ptr = ptr;             data_list.data_type = data_type;             data_list.active = TRUE;             return TRUE;           }}

my plan was to manipulate the actual data pointed to by data_t->data_ptr by dereferencing it.

Is it possible to cast the data_ptr to some other type(say int) and then dereference it to alter the data it points to? If so what would this look like in code, I'm having a hard time imagining it.

Or would I be forced to do something like this...
typedef sruct{     int *int_data_ptr;     float *float_data_ptr;     BOOL *bool_data_ptr;     int data_type;       BOOL active;}data_t;data_t data_list[N];BOOL register_data(int i,  void* ptr, int data_type ){      if ( ! data_list.active) {                          if (data_type == INT_TYPE)                      data_list.int_ptr = (int*)ptr;             else if (data_type == FLOAT_TYPE)                      data_list.float_ptr = (float*)ptr;              se if (data_type ==BOOL_TYPE)                      data_list.bool_ptr = (BOOL*)ptr;                                   data_list.data_type = data_type;             data_list.active = TRUE;             return TRUE;   }
Quote:Original post by ari556655
Is it possible to cast the data_ptr to some other type(say int) and then dereference it to alter the data it points to?

Sure.
int num = 21;void *vp = &numint* ip = reinterpret_cast<int*>(vp);*ip = 12;
Your posts look like you are ready to be introduced to templates.

A template type could use a pointer of whatever you needed. You want a pointer to int? You got it! You want a pointer to float? You got it! You want a pointer to InventoryItems? You got it! And if you still need avoid pointer, you can do that too.


If you are in the unfortunate situation where that isn't possible due to external constraints, then store the void pointer and use an enum to indicate what type to cast your void* to. It is better than a raw int because the compiler can help you ensure it is known.
The OP could also keep his sanity and just use boost::variant.
The original posters code looks like C not C++ (notice the BOOL instead of bool - and the typedefs) ... so I assume they cannot use boost, or templates. [if I'm wrong OP, then follow the advice of the previous posters]

But there are 2 basic things to understand in C when you want to do "dynamic" typing. you have UNIONS and you have POINTER CASTING (which is shown in a previous post).

You would NOT normally allocate multiple pointers as in your second example, because that would use memory for each. You would either keep using just 1 void* in your type, but CAST IT to the right type in code. Or you could use a union similar to what you showed. But really the union case isn't normally used for pointers, it is normally used for NON-pointers, so if you wanted to have an efficient variant class you would make your node have a union for the dynamic data section ... where the members would be:

typedef union {
int i;
float f;
BOOL b;
} dynamic_value_t;

typedef struct {
dynamic_value_t value;
int data_type;
BOOL active;
} data_t;

then it would just use the memory of the largest single option ...

This topic is closed to new replies.

Advertisement