这里(双*)的目的是什么? 我理解:
double d1 = *&a;
会给我a的地址值,但是加上(double *)将值1.4854e-313存储到d1中。为什么是这样?什么是打字?我是否已从未定位的内存中写入或读取?
int main () {
int a = 17;
double d1 = *(double*)&a ;
std :: cout << "\na = " << a << ", &a = " << & a ;
std :: cout << "\nd1 = " << d1 << ", &d1 = " << & d1 ;
}
答案 0 :(得分:2)
这是类型惩罚,但它也是未定义的行为。在大多数平台上,int
与double
的大小不同,这意味着向int
指针投射double
指针,然后从中读取,将从堆叠您无法访问的数据。
从字面上看,正在发生的事情是d1
被分配了a
及其周围存储的比特。因为这些位是任意的(并且可能从堆栈中读取垃圾),所以它的值几乎可以是任何东西。
不言而喻,你不应该这样做。在理想情况下,Type-Punning只是几乎没有定义的行为,绝对不会使用你在这里使用的方法。
答案 1 :(得分:2)
这里发生的事情是,您正在a
重新int
,强制转移到double
。
让我分解一下:
&a
获取int *
类型的指针到变量a
。
然后,使用(double *)
,您将重新指定此类型double *
。
最后,使用*
解除引用指向double
的指针。
所以,总而言之,您将指针指向a
,将其重新标记为double*
,取消引用它,并将值指定给变量d1
。
这被称为类型惩罚,正如其他人所提到的那样,这很糟糕,因为int
和double
这两种类型可能在内存中占用不同的字节数。
假设int
在您的系统上定义为4个字节,double
为8个字节。然后这是一个问题,因为你告诉你的系统“嘿,看,你可以在这个地址读取接下来的8个字节,而不是实际有效数据的4个字节。”谁知道接下来的4个字节是什么?行为是 undefined ,你基本上保证读垃圾。
答案 2 :(得分:0)
它与下面的代码类似。如果它分配int
并获得double
,它也有UB,但它不会访问外星人的内存,也不会破坏严格的别名。
union mixed_types {
int a;
double d1;
};
int main () {
mixed_types bad;
bad.a = 17;
double d1 = bad.d;
std :: cout << "\na = " << a << ", &a = " << & a ;
std :: cout << "\nd1 = " << d1 << ", &d1 = " << & d1 ;
}