Search code examples
ccastingmemcpy

In memcpy like a cast?


I am analyzing software not written by me and I found this instruction:

memcpy((void *)&vardata.value, (void *)&fvalue, sizeof(vardata.value));

assuming that:

  • vardata.value is a long value
  • fvalue is a float value

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

Solution

  • 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.