I am analyzing software not written by me and I found this instruction:
memcpy((void *)&vardata.value, (void *)&fvalue, sizeof(vardata.value));
assuming that:
I know (more or less) what memcpy does, but in this case what is exactly memcpy doing? How much would vardata.value be if fvalue were, for example, 12.65? Is it some kind of casting?
If I try to print the variables after memcpy using:
printf("VAL 1 = %ld VAL 2 = %.2f\n", vardata.value, fvalue);
the output is:
VAL 1 = 1095394918 VAL 2 = 12.65
memcpy()
does as its name suggests: it copies memory. Its arguments are a void*
base pointer for the destination memory, a const void*
base pointer for the source memory to be copied, and a number of bytes to copy.
The first problem is you are copying sizeof(long)
bytes from the start of the float
into the receiving long
. That float
is a 32-bit floating-point number; long
, on the other hand. is a signed long integer
value. If your long
size is 64 bits, for example, the memcpy()
will therefore read not just the four bytes of the float
, but another four bytes beyond it, which could cause a memory fault and will definitely copy arbitrary (indeterminate) data even if it doesn't crash.
The second problem is that even if your long
is a 32-bit signed integer, memcpy()
simply copies the bytes from your float
into the bytes in your long
, byte by byte. It is not aware, and does not care, that the two pieces of memory use different formats (float
: IEEE 754; long
: two's complement signed integer). It just slaps the bytes from one place into the other.
What it will not do is a numeric conversion between them.
What the code (presumably) needs, and what its writer (presumably) meant is vardata.value = (long)fvalue;
. In this way, the correct conversion is achieved by the cast.