Thread: memcpy to struct

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    932

    memcpy to struct

    Im trying to copy a string to a struct with memcpy and I get:
    error C2440: 'static_cast' : cannot convert from 'imagesize' to 'void *'|

    Code:
     
    struct imagesize
    {
        unsigned short len; /* 2-bytes */
        unsigned char c;    /* 1-byte */
        unsigned short x;   /* 2-bytes */
        unsigned short y;   /* 2-bytes */
    }; //sizeof(struct imagesize) == 7
    
    int main()
    {
        std::ifstream ifs(filename, std::ios::binary);
        string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
    
        size_t pos = str.find(pattern);
    
        if (pos != string::npos)
        {
            struct imagesize img;
    
    
            /* using memcpy to copy string: */
            memcpy(static_cast <void*> (img), &str[pos+6], sizeof(struct imagesize));
    
        }
    }
    Using Windows 10 with Code Blocks and MingW.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    You need "reinterpret_cast", not "static_cast". Also, you'd want to use "&img"...
    Devoted my life to programming...

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    (Almost) any pointer type is implicitly convertible to void*. You don't need a cast at all. The problem is that you aren't taking its address.
    Still, I recommend against memcpy. Read into the individual members using operator >> instead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    sizeof(struct imagesize) == 7
    O_o

    The structure could be seven bytes, but other sizes are also valid.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    Thanks you both, Ill try with '<<' then.
    Using Windows 10 with Code Blocks and MingW.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    Quote Originally Posted by phantomotap View Post
    O_o

    The structure could be seven bytes, but other sizes are also valid.

    Soma
    It depends from the computer, right?
    Using Windows 10 with Code Blocks and MingW.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It depends on your compiler and OS.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    It depends from the computer, right?
    O_o

    You are partially correct.

    The structure size depends on the computer in that the elements are given sizes appropriate for the execution environment. However, a compiler can use different labels for different sizes. The size of `char` is required to be one, but the size of `short` isn't necessarily going to be two. In practice, you'll find that the size of `short` is usually two. The larger integers aren't as convenient.

    That said, I was actually referencing padding. I'd recommend looking for more information, but the simple view is that a blank is placed after the `char` so that the next has the correct alignment. [Edit]Basically, the size of the structure may be larger than the sum of the size of every element.[/Edit]

    Soma
    Last edited by phantomotap; 07-29-2015 at 11:11 AM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    Thanks for the explanation.

    Quote Originally Posted by Elysia View Post
    I recommend against memcpy. Read into the individual members using operator >> instead.
    Yes, memcpy() swap the endianness also unfortunately. Are you sure that I can read with this '>>' operator in the individual members? Isnt this the left shift operator?

    Code:
    img.x << str[pos+5];
    Maybe you meant this:
    Code:
    img.x = str[pos+5];
    Still dont know how to read to hex values to a short? I need 0x02 and 0x1B to make 0x21B. I guess Ill have to use a string to int function.
    Last edited by Ducky; 07-29-2015 at 01:03 PM.
    Using Windows 10 with Code Blocks and MingW.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Ducky View Post
    Are you sure that I can read with this '>>' operator in the individual members? Isnt this the left shift operator?
    Yes, you can. This is also a stream operator (extraction operator).
    Also, upgrade to VS 2015.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Yes, memcpy() swap the endianness also unfortunately.
    O_o

    No. The `memcpy` function does no such thing. You are likely reading the bytes in the correct order. You are likely copying the bytes in the correct order. The endianness of the file is simply different than the machine you are using to read the file. You aren't facing some idiotic bug in `memcpy`; you are facing the reality of processing files. You need to interpret the file as the file was written not simply as you might wish you could interpret the file.

    Now, the question is if you have binary data. Do you have binary data or simply data you don't want any newline conversion?

    If you have binary data, you can't use the extraction operator.

    *shrug*

    You should process a binary file by reading a chunk with `std::ifstream::read` into a buffer, pulling the relevant bits out of the buffer, and giving the bits semantics by tossing them at a relevant structure. You are already trying to follow the strategy. I'd suggest moving to `std::vector<unsigned char>` instead of `std::string` for storage. You can `memcpy` the relevant bits, after the search, into the structure.

    Yes. You will have to account for differences in endianness yourself. The `memcpy` function doesn't know about endianness; the `memcpy` function doesn't even know that you are copying to a `unsigned short` variable. The majority of environments provide `htonl` and friends to help with the process.

    You could also ignore all of my comments in favor of using a library which has a more sophisticated serialization layer like "Boost" or similar.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  12. #12
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    I have binary data so I will use 'std::ifstream::read' then.

    I think I wont use a library for now in order to understand better the underlying mechanism.

    Thanks for the clarification, it's well explained.



    Using Windows 10 with Code Blocks and MingW.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memcpy not doing its job
    By Hawkin in forum C Programming
    Replies: 4
    Last Post: 11-11-2010, 12:17 PM
  2. memcpy with struct and pointer
    By neeraj_rn in forum C Programming
    Replies: 10
    Last Post: 08-28-2010, 07:46 AM
  3. using memcpy?
    By nyekknyakk in forum C Programming
    Replies: 1
    Last Post: 08-19-2010, 07:47 PM
  4. memcpy
    By m37h0d in forum C++ Programming
    Replies: 28
    Last Post: 04-12-2008, 09:10 PM
  5. memcpy()
    By Moni in forum C++ Programming
    Replies: 3
    Last Post: 09-05-2006, 05:31 AM