Conversion from void* to a point of a class

  • Thread starter Thread starter Charles Zhang
  • Start date Start date
C

Charles Zhang

I want to know to the following in a safe manner (the following code
will be dangerous if p does not contain a pointer to MyClass). I would
like someone to show me a better way (either throw an exception or
return value which I can check if the cast is allowed or not.

void* p;
...
MyClass* pClass = (MyClass*)p;

Thank you very much for your help.

Charles Zhang
 
Hi Charles,
void* p;
...
MyClass* pClass = (MyClass*)p;
Thank you very much for your help.


initialize p == NULL, and check whether
p has some valid address pointing at before
you do the casting. NEVER use uninitialized
variables like you wrote here! They will point
to somewhere but not to your allocated memory
for your Class in this example!

something like:

void *p == NULL;

.....
.....
.....

if(p != NULL){
MyClass* pClass = (MyClass*)p;
}else{
//some invalid pointer handling code here
//a messagebox or some console output or whatever
//you like to handle this situation
}


Regards

Kerem

--
 
Of course, I will make sure the void pointer is not NULL. However, a
non-null pointer is not necessary a valid pointer of MyClass. Your code
will cause a run time error which could crash the application.

Charles Zhang
 
Thank you very much. But I actually tried to use dynamic_cast, but I got
an compiler error

void* p = NULL;
....
....
MyClass* pClass = dynamic_cast<MyClass*>(p);

The compiler error is: "invalid expression type for dynamic_cast."

Then I changed the line to:
MyClass* pClass = dynamic_cast<MyClass*>((MyClass*)p);

Now, it compiles. But when p is not an valid pointer to MyClass, now run
time exception was thrown. Which could cause the application to crash.

Charles Zhang
 
dynamic_cast requires a polymorphic type: p must point to an object with at
least one virtual function. Usually this kind of mistake is caught at compile
time, but due to indirection (p) compiler is not be able to do that (and of
course, an invalid pointer is not a polymorphic type).

Regards
 
Well, that is true, dynamic_cast does not work for void-pointers - once
you have converted your MyClass* pointer to a void* you have voluntarily
given up all type information and there is no safe way back.

To convert a void pointer back to MyClass*, you have to use
reinterpret_cast, which in this context is basically the same as the
C-style cast you used initially. There is, of course, no guarantee that
the object returned by reinterpret_cast is indeed a valid object of
MyClass or rather some other garbage.

If possible by any measure, avoid using void-pointers in C++ in the
first place - there is almost always a better way to do it. In C, where
no such thing like RTTI exists, there is one common idiom you could use
in C++ as well if you are urged to use void pointers: To provide at
least a certain degree of sanity checking before using a casted pointer,
include some signature/magic field in the struct/class and check that it
contains the expected value before using it:

void *p = ...
MyClass *my = reinterpret_cast<MyClass*>(p);
if ( my->Signature != MYCLASS_SIGNATURE )
{
// this pointer is invalid
}
else
{
// it is likely the the pointer is valid
}

If you can avoid using void-pointers, do that - it may save you a lot of
trouble.

--Johannes
 
Johannes said:
Well, that is true, dynamic_cast does not work for void-pointers - once
you have converted your MyClass* pointer to a void* you have voluntarily
given up all type information and there is no safe way back.

To convert a void pointer back to MyClass*, you have to use
reinterpret_cast, which in this context is basically the same as the
C-style cast you used initially.

Johannes:

You can (and should) use static_cast to convert void pointer. Using
reinterpret_cast is usually an indication that you are doing something
non-portable (which casting a void pointer usually is not).
 
Back
Top