让我们假装一些错误的代码将一个int值放入浮点地址。 一般来说,我怎样才能找回那个int值?
答案 0 :(得分:2)
请注意以下答案:下面的代码模拟了问题(使用int
在为float
保留的内存位置中存储reinterpret_cast
的问题,然后再次使用reinterpret_cast
解决问题。这打破了 strict-aliasing rule (3.10 / 10 C ++标准),它声明通过(g)与对象的实际类型不匹配的类型的左值访问对象(在某种意义上匹配),调用未定义的行为。
由于这个原因,不应该使用下面给出的代码,并且解决方案,即使用reinterpret_cast
,至少是危险的(虽然它可能经常工作)。有关正确的解决方案,请参阅Steve Jessop's answer。感谢他指出我的错误(见评论)。
原始答案:
如果您有存储值的地址,并且地址是否正确对齐以进行整数访问,那么您应该可以使用reinterpret_cast
:
int main()
{
/* An integer and an uninitialized float: */
int original = 45;
alignas(int) alignas(float) float f;
float *p = &f;
/* "Erroneously" putting an int into the address of the float: */
*reinterpret_cast<int*>(p) = original;
/* Retrieving the int (this is what you were looking for): */
int retrieved = *reinterpret_cast<int*>(p);
std::cout << "Original: " << original
<< ", Stored float: " << f
<< ", Retrieved: " << retrieved
<< std::endl;
return 0;
}
(上面使用的关键字alignas
来自C ++ 11。你的编译器可能不接受它。无论如何,代码的那部分是我模仿问题的方式,它不是一个必不可少的部分。解决方案。)
答案 1 :(得分:1)
reinterpret_cast<int*>
的答案违反了严格的别名,并且行为未定义。
如果您想使用已定义的行为执行此操作:
int read_int_from_float(const float &f) {
int result;
std::memcpy(&result, &f, sizeof(result));
return result;
}
这是在检查float
和int
具有相同尺寸后。它们不需要具有相同的对齐方式。