我有一个void
指向内存地址的指针。那我做
int
指针=void
指针
float
指针=void
指针
然后,取消引用它们就可以获取值。
{
int x = 25;
void *p = &x;
int *pi = p;
float *pf = p;
double *pd = p;
printf("x: n%d\n", x);
printf("*p: %d\n", *(int *)p);
printf("*pi: %d\n", *pi);
printf("*pf: %f\n", *pf);
printf("*pd: %f\n", *pd);
return 0;
}
解引用pi
(int
指针)的输出为25。但是,解引用pf
(float
指针)的输出为0.000。还取消引用pd
(double
指针)会输出不断变化的负分数吗?
为什么会这样并且与字节序有关(我的CPU是小字节序)?
按照C
标准,您允许将任何指针转换为指针void *
并将其转换回,其效果相同。
引用C11
第6.3.2.3章
[...]指向任何对象类型的指针都可以转换为指向
void
并返回的指针;结果应等于原始指针。
这就是为什么在将void指针投射到int *
,取消引用并打印结果时,它可以正确打印的原因。
但是,标准不能保证您可以取消引用该指针为其他数据类型。它实质上是在调用未定义的行为。
所以,解引用pf
或pd
获得float
或者double
是不确定的行为,因为你想读分配的内存int
为一个float
或double
。有一个明显的错误案例导致UB。
为了详细说明,int
和float
(和double
)有不同的内部表示,所以试图将指针转换为另一种类型,然后尝试取消引用来获取值在其他类型将无法正常工作。
相关C11
,第§6.5.3.3章
[...]如果操作数的类型为“类型的指针”,则结果的类型为“ type”。如果为指针分配了无效的值,则一元运算
*
符的行为是不确定的。
对于无效值部分,(强调我的)
一元*运算符用于取消对指针的引用的无效值包括空指针,针对所指向对象的类型不适当地对齐的地址以及对象生命周期结束后的地址。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句