C/C++ pointer tricks (saving pointer to int, and translating back)
As title says, I'm currently doing some small hacks with pointers in C++, but something isn't working out here's what I got:
uintptr_t texture_pointer = (int)((void*) &texture);
Where texture is开发者_开发知识库 a class; this seems to work fine, as I'm getting a pointer value out, and I have insured that I'm getting the same value into my other function, which is supposed to get the object back; this is the code that fails:
std::cout << "C++ BEFORE: " << texture_pointer << std::endl;
Texture texture = *(Texture*)((void*) texture_pointer);
std::cout << "C++ AFTER: " << (uintptr_t)((void*) &texture) << std::endl;
The output I was excepting; was that the same number for both, however I'm getting two different numbers, hence why I think there must be an error, but I can't seem to find it.
Example output:
C++ BEFORE: 2685236
C++ AFTER: 2684960
This line:
Texture texture = *(Texture*)((void*) texture_pointer);
creates a new Texture
object as a copy of the original one. Obviously, this has a different address to the old one.
You could do this:
Texture &texture = *(Texture*)((void*) texture_pointer);
(i.e. create a reference to the old one).
But in general, messing about with pointers like this is more trouble than it's worth.
For casting to and from void pointers, use static_cast
. For casting to and from integers, use reinterpret_cast
:
SomeType* p;
// Make sure the type can hold a pointer.
std::uint64_t i = reinterpret_cast<std::uint64_t>(p);
...
SomeType* q = reinterpret_cast<SomeType*>(i); // Guaranteed to yield p back
As well as the errors pointed out already in other answers, this line is incorrect and may well fail on 64 bit systems (LP64):
uintptr_t texture_pointer = (int)((void*) &texture);
It should be:
uintptr_t texture_pointer = (uintptr_t)&texture;
(assuming you want to use C-style casts rather than proper C++ casts for some reason).
Initially, you take the address of an object allocated on the stack, not on the heap. The line:
Texture texture = *(Texture*)((void*) texture_pointer);
then copies that object into another object allocated on the stack. Then you take the address of the second address.
As you are dealing with two different objects, you have two different addresses.
If I have counted the '*'s correctly this line
Texture texture = *(Texture*)((void*) texture_pointer);
creates a copy of whatevery texture_pointer points to.
so, texture and *texture_pointer are different storage locations and that's why &texture and texture_pointer have different values.
Texture texture = *(Texture*)((void*) texture_pointer);
This line creates a new object and assigns the object pointed to by texture_pointer to it. That's different from creating a pointer and making it point to an object. When you assign one object to another, you're basically copying contents of the old one into the new one. It makes sense, then, that the two printed addresses are different -- they're the addresses of two different objects.
精彩评论