简体   繁体   中英

Convert pointer to int and back to typed object

I need a simple way to convert a pointer to an int, and then back to the pointer. I need it as an int for portability, since an int is easier to carry around in my project than a pointer.

Start player and return pointer:

SoundPlayer* player = new FxPlayerTiny();
return (int)player; // this works, but is it correct?

Stop player using pointer int:

FxPlayerTiny* player = static_cast<FxPlayerTiny*>((int*)num); // this gives me an error
FxPlayerTiny* player = (FxPlayerTiny*)((int*)obj); // this works, but is it correct?
delete player;

The best thing to do is to fix your project so it can deal with pointers. Integers and pointers are two different things. You can convert back and forth, but such conversions can lose information if you're not careful.

Converting a pointer value to int and back again can easily lose information, depending on the implementation and the underlying platform. For example, there are systems on int is smaller than a pointer. If you have 32-bit int s and 64-bit pointers, then converting a pointer to an int and back again will almost certainly give you an invalid pointer.

It's very likely that long or unsigned long is wide enough to hold a converted pointer value without loss of information; I've never worked on a system where it isn't. (Personally, I tend to prefer unsigned types, but not for any really good reason; either should work equally well.)

So you could write, for example:

SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<unsigned long>player;

and convert the unsigned long value back to a pointer using reinterpret_cast,SoundPlayer*> .

Newer implementations provide typedefs uintptr_t and intptr_t , which are unsigned and signed integer types guaranteed to work correctly for round-trip pointer-to-integer-to-pointer conversions. They were introduced in C99, and optionally defined in the <stdint.h> header. (Implementations on which pointers are bigger than any integer type won't define them, but such implementations are rare.) C++ adopted them with the 2011 standard, defining them in the <cstdint> header. But Microsoft Visual C++ does support them as of the 2010 version.

This guarantee applies only to ordinary pointers, not to function pointers or member pointers.

So if you must do this, you can write:

#include <cstdint>
SoundPlayer* player = new FxPlayerTiny();
return reinterpret_cast<std::uintptr_t>player;

But first, consider this. new FxPlayerTiny() gives you a pointer value, and you're going to want a pointer value. If at all possible, just keep it as a pointer. Converting it to an integer means that you have to decide which of several techniques to use, and you have to keep track of which pointer type your integer value is supposed to represent. If you make a mistake, either using an integer type that isn't big enough or losing track of which pointer type you've stored, the compiler likely won't warn you about it.

Perhaps you have a good reason for needing to do that, but if you can just store pointers as pointers your life will be a lot easier.

It is not recommended to use an int for portability, especially because sizeof (int) and sizeof (void*) could differ (for example when compiling for Windows x64). If ints are needed for a user interface, it maybe would be better to use a table of pointers and accessing them via indices.

However, if you want to convert an pointer to an integer and vice versa a simple conversion is enough but it's just the same, if sizeof *int) == sizeof (void*) .

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