Thread: strange behaviour with memcpy

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    3

    strange behaviour with memcpy

    dear all, I am sorry, I have just started to use C.
    I have a strange thing here and would appreciate if someone can explain why this working as it is. If I uncomment one of the memcpy's, the 2nd printf changes. I'd expect that it only changes once I uncomment the last memcpy.

    (The solution might be a different way and I'd more then happy if someone can point me to the right direction. I want to have a double example 25 written in binary form and right order in a file for example as 40390000)
    But now to my problem:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
    
            FILE *flat;
            double fl=1280,*ptr;
            int flr=0,b;
    
            flat = fopen ("floats.txt","wb+");
            ptr=&fl;
    
            memcpy(&flr,&fl,8); // comment this out, flr changes, why?
    
            memcpy(&flr,&ptr[0],4); 
    
            printf("x:%X %p\n",flr,&flr);
    
            b=(flr&0xff000000)>>24  | (flr&0xff0000)>>8  | (flr&0xff00)<<8  | (flr&0xff)<<24;
    
            fwrite(&b,4,1,flat);
            fclose(flat);
            printf("done\n");
            return 0;
    
    }
    Thanks
    D

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Because you're copying stuff on top of it?

    Also since flr is probably 4 bytes, copying 8 bytes on top of it is probably also changing b, but you wipe that out before you see it...

  3. #3
    Registered User
    Join Date
    Aug 2011
    Posts
    3
    Thanks for your reply.
    But how would I achive to printf as %X with only one memcpy? with those two it work, but not with one... that's strange for me...
    also, if I use memcpy(&flr,&ptr[0],8); it's the same.
    Last edited by denimjeans; 08-16-2011 at 01:25 PM.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    No matter how you're doing this... you are still trying to copy an 8 byte double into a 4 byte int... you're going to get the wrong answer, either way.

    Floats and doubles are not simple binary values. Look it up on Google... you can't just copy one to another without causing yourself problems.

    You can however use... integer = (int) floater; and get the right value. The only consequence is that you only get the whole number, not the decimal points.

    What exactly are you trying to accomplish?

  5. #5
    Registered User
    Join Date
    Aug 2011
    Posts
    3
    but if I do it with long int and %lX, which should also be 8 bytes it's the same result. after uncommenting the first memcpy the result changes.
    What I am trying to achive is: I need to have the hex value of a double value. the first 4 bytes are sufficient.
    For example:
    decimal 1280 is as double in HEX 0x4094000000000000 accourding to the IEEE 754 standard. And yes, you are so right, floating / double are not that simple as I thought. )
    I want to have the 40940000 to be written in the binary file once I have a decimal number 1280 for example. For Decimal 25 the value 40390000...... So once I check the file with xxd there should be 40940000 ....
    can you help?

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    long int is probably also not 8 bytes. long long int, sure.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Well for starts... 1280 decimal is not 4094000 in hex... it's 500 hex. 25 decimal as hex is 19.

    If you're trying to write binary values to a file, why are you converting them to ints?
    You can just use...
    Code:
    // assuming an open file...
    
    float value = 1280.0;
    
    fwrite(&value,sizeof(float),1,FILE);
    To get the value back, just use fread.

    I'm sorry if I'm misunderstanding all this work you're going through... but it seems to me you're overcomplicating the daylights out of this...
    Last edited by CommonTater; 08-16-2011 at 02:25 PM.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You're code is all messed up:
    Code:
            flat = fopen ("floats.txt","wb+");
    Check flat to see if it's null before using it.

    Code:
            memcpy(&flr,&fl,8); // comment this out, flr changes, why?
    flr is an int, probably 4 bytes, and fl a double. You can't copy 8 bytes into 4, that's undefined behavior. Try making flr a "long long", and using %llX (ell ell ex). You very well may be copying over the address stored in ptr and thus copying from a bogus address in the second memcpy (&ptr[0] is equivalent to ptr, and is more confusing since ptr is not an array nor does it point to one).

    The thing about undefined behavior is...well...it's undefined. Anything or nothing may happen, now, in 5 minutes or 5 years. It may crash, give unexpected results or trash part of your system. Avoid it at all costs.

    You're using "wb+" and fwrite, which means you're writing binary data, so just do fwrite(&b, sizeof(b), 1, flat). Note that if you squish 8 bytes of a double to a 4 byte int, you may get an overflow and will certainly truncate any decimal portion of the number you have, i.e. you will lose significant data.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strange scanf behaviour
    By cavva in forum C Programming
    Replies: 3
    Last Post: 08-10-2009, 12:44 PM
  2. Strange behaviour of GCC
    By BlackOps in forum C Programming
    Replies: 14
    Last Post: 07-29-2009, 06:44 PM
  3. memcpy strange
    By robid1 in forum C++ Programming
    Replies: 5
    Last Post: 08-22-2004, 12:37 AM
  4. strange behaviour.......
    By surdy in forum C Programming
    Replies: 2
    Last Post: 05-01-2004, 11:50 AM
  5. Strange behaviour
    By PrivatePanic in forum Windows Programming
    Replies: 11
    Last Post: 07-23-2002, 12:54 AM