C / C ++指针技巧(将指针保存到int,并转换回来)

时间:2011-09-19 11:34:36

标签: c++ pointers casting void-pointers

正如标题所说,我现在正在做一些带有C ++指针的小黑客,但是有些东西在这里没有用到我得到的东西:

uintptr_t texture_pointer = (int)((void*) &texture);

纹理是一个类;这似乎工作正常,因为我得到一个指针值,我已经保证我得到了相同的值到我的其他函数,这应该得到对象;这是失败的代码:

std::cout << "C++ BEFORE: " << texture_pointer << std::endl;
Texture texture = *(Texture*)((void*) texture_pointer);
std::cout << "C++ AFTER: " << (uintptr_t)((void*) &texture) << std::endl;

我的输出除外;是两个相同的数字,但是我得到两个不同的数字,因此为什么我认为必定有错误,但我似乎无法找到它。

示例输出:

C++ BEFORE: 2685236
C++ AFTER: 2684960

6 个答案:

答案 0 :(得分:9)

这一行:

Texture texture = *(Texture*)((void*) texture_pointer);

创建 Texture对象作为原始对象的副本。显然,这与旧的地址不同。

你可以这样做:

Texture &texture = *(Texture*)((void*) texture_pointer);

(即创建对旧旧的引用)。

但总的来说,弄乱像这样的指针比它的价值更麻烦。

答案 1 :(得分:4)

要与void指针进行强制转换,请使用static_cast。要使用整数进行强制转换,请使用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

答案 2 :(得分:1)

除了在其他答案中已经指出的错误之外,这一行不正确,并且可能在64位系统(LP64)上失败:

uintptr_t texture_pointer = (int)((void*) &texture);

应该是:

uintptr_t texture_pointer = (uintptr_t)&texture;

(假设您出于某种原因想要使用C风格的强制转换而不是正确的C ++强制转换)。

答案 3 :(得分:0)

最初,您获取在堆栈上分配的对象的地址,而不是在堆上。这一行:

Texture texture = *(Texture*)((void*) texture_pointer);
然后

将该对象复制到堆栈上分配的另一个对象。然后你取第二个地址的地址。

当您处理两个不同的对象时,您有两个不同的地址。

答案 4 :(得分:0)

如果我在这行中正确计算了'*'

Texture texture = *(Texture*)((void*) texture_pointer);

创建一个whatevery texture_pointer指向的副本。

所以,texture和* texture_pointer是不同的存储位置,这就是为什么&amp; texture和texture_pointer有不同的值。

答案 5 :(得分:0)

Texture texture = *(Texture*)((void*) texture_pointer);

此行创建一个新对象,并将texture_pointer指向的对象分配给它。这与创建指针并使其指向对象不同。当您将一个对象分配给另一个对象时,您基本上将旧对象的内容复制到新对象中。那么,有意义的是,两个打印的地址是不同的 - 它们是两个不同对象的地址。