I have a void
pointer pointing to a memory address. Then, I do
int
pointer = the void
pointer
float
pointer = the void
pointer
and then, dereference them go get the values.
{
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;
}
The output of dereferencing pi
(int
pointer) is 25.
However the output of dereferencing pf
(float
pointer) is 0.000.
Also dereferncing pd
(double
pointer) outputs a negative fraction that keeps
changing?
Why is this and is it related to endianness(my CPU is little endian)?
As per C
standard, you'er allowed to convert any pointer to void *
and convert it back, it'll have the same effect.
To quote C11
, chapter §6.3.2.3
[...] A pointer to any object type may be converted to a pointer to
void
and back again; the result shall compare equal to the original pointer.
That is why, when you cast the void pointer to int *
, de-reference and print the result, it prints properly.
However, standard does not guarantee that you can dereference that pointer to be of a different data type. It is essentially invoking undefined behaviour.
So, dereferencing pf
or pd
to get a float
or double
is undefined behavior, as you're trying to read the memory allocated for an int
as a float
or double
. There's a clear case of mismtach which leads to the UB.
To elaborate, int
and float
(and double
) has different internal representations, so trying to cast a pointer to another type and then an attempt to dereference to get the value in other type won't work.
Related , C11
, chapter §6.5.3.3
[...] If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary
*
operator is undefined.
and for the invalid value part, (emphasis mine)
Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.
In addition to the answers before, I think that what you were expecting could not be accomplished because of the way the float numbers are represented.
Integers are typically stored in Two's complement way, basically it means that the number is stored as one piece. Floats on the other hand are stored using a different way using a sign, base and exponent, Read here.
So the main idea of convertion is impossible since you try to take a number represented as raw bits (for positive) and look at it as if it was encoded differently, this will result in unexpected results even if the convertion was legit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With