use memcpy() to copy one structure to another

Discussion in 'C Programming' started by Sourcerer, Jun 15, 2004.

  1. Sourcerer

    Sourcerer Guest

    Hi all.

    Can I do this to duplicate the contents of struct a in struct b

    struct myStruct a, b, *aptr, *bptr;
    aptr = a;
    bptr = b;
    Do something to initialize contents of structure a
    memcpy(bptr, aptr, sizeof(myStruct));

    Or is not not a good idea to assume the memory used
    by my structure is contiguous ?
    should I instead do it field by field.

    Kev.
     
    Sourcerer, Jun 15, 2004
    #1
    1. Advertisements

  2. Sourcerer

    Chris Dollin Guest

    Illegal. Did you mean &a?
    Ditto &b.
    It may have gaps, but sizeof will cover them all. But why not

    memcpy( bptr, aptr, sizeof (*bptr) );

    if you're set on using memcpy?
    What's wrong with

    a = b;

    ?
     
    Chris Dollin, Jun 15, 2004
    #2
    1. Advertisements

  3. Sourcerer

    Thomas Pfaff Guest

    memcpy (&b, &a, sizeof b); or simply b = a;
     
    Thomas Pfaff, Jun 15, 2004
    #3
  4. Sourcerer

    Sourcerer Guest

    Wow ! that was fast.

    I hadn't realized a = b would do it.

    so, I could have

    struct mystruct
    {
    char str[50];
    }

    struct mystruct a, b;
    sprintf(a.str, "Testing 123");
    b = a;

    and then b.str would also contain "Testing 123" ?
     
    Sourcerer, Jun 15, 2004
    #4
  5. aptr = &a;
    bptr = &b;
    Try these:
    b = a;
    memcpy(&b, &a, sizeof(struct myStruct));

    I believe that the total space occupied by a structure
    is contiguous; however, the compiller is allowed to
    add padding between the fields.

    When copying one structure to another, memcpy can be
    used. But you should have a policy when it comes
    to pointer fields:
    1. Copy only the pointer and have multiple pointers
    to one object.
    2. Create a new copy of the target object, thus having
    two copies of the target object.
    3. Reference counting: multiple pointers to one
    object, but the number of references must be zero
    before the target object is deleted.

    I would copy field by field when copying to or from
    a buffer (unsigned char array). Padding bytes may
    be copied from one structure to another, but a buffer
    may not have padding between the fields.


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c++-faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c++/faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    http://www.sgi.com/tech/stl -- Standard Template Library
     
    Thomas Matthews, Jun 15, 2004
    #5
  6. Sourcerer

    Guest Guest

    Juste use:
    b = a;

    - Dario
     
    Guest, Jun 15, 2004
    #6
  7. Sourcerer

    CBFalconer Guest

    That better be:

    aptr = &a;
    bptr = &b;

    but you can duplicate the contents by:

    b = a;

    What you cannot do is check equality etc. by:

    if (b == a) ...; /* not allowed */

    structs are not arrays.
     
    CBFalconer, Jun 15, 2004
    #7
  8. Why not
    struct myStruct a = { /* initialize a */ }, b;
    b = a;
    and forget all your side issues.
     
    Martin Ambuhl, Jun 15, 2004
    #8
  9. Sourcerer

    Alex Fraser Guest

    Does the assignment above invoke undefined behaviour if not all members of a
    are initialised?

    What about the "equivalent" memcpy()?

    Alex
     
    Alex Fraser, Jun 15, 2004
    #9
  10. Just how, given the presence of an initializer, do you propose to
    partially initialized the structure?
    Who cares about function calls when a simple assignment will do?
     
    Martin Ambuhl, Jun 15, 2004
    #10
  11. Sourcerer

    Default User Guest


    If an array is partially intialized, the rest of the elements are
    default initialized. So no undefined behavior, as all elements will have
    values.



    Brian Rodenborn
     
    Default User, Jun 16, 2004
    #11
  12. Sourcerer

    CBFalconer Guest

    structures do not have to be initialized at declaration time.
    Since a structure with an uninitialized component is an
    uninitialized structure, copying it via structure assignment
    should be undefined behaviour. Yet I expect it will go unpunished
    on most machines other than the DS9000.
     
    CBFalconer, Jun 16, 2004
    #12
  13. Sourcerer

    Alex Fraser Guest

    Thank you, that makes sense. I was thinking in practical terms when I
    phrased the question: assigning a structure where the source is partially
    initialised is much more likely to happen than where it is completely
    uninitialised, but the effect is identical in either case.

    I suppose, in fact, it is no different to:

    int a, b; /* uninitialised */
    b = a; /* undefined behaviour (since a may be a trap representation?) */

    But I wonder if the same still applies with the notionally equivalent
    memcpy(). I think that question boils down to:

    unsigned char a, b; /* uninitialised */
    b = a; /* undefined behaviour? */

    Alex
     
    Alex Fraser, Jun 16, 2004
    #13
  14. Sourcerer

    kal Guest

    I suppose anything is possible. It may be that the type "int"
    is 33 bits in size and at declaration time bit 32 is set to 1.
    It is reset to zero only when a value is explicitly assigned to
    the variable. Any attempt to read the contents of the variable
    when bit 32 is not zero terminates the program execution.

    But for us bozos who make do with 16 or 32 bit integers, all bit
    patterns represent valid integer values. Hence, unitialized does
    not means "undefined" or "trap representation", it just means that
    the value in it is not the one we want to start with.

    Can someone expound on "trap representation" vis-a-vis integers?
     
    kal, Jun 18, 2004
    #14
  15. Sourcerer

    Richard Bos Guest

    That's one possibility, yes.
    Nope. Usually, but not necessarily. That is, yes, INT_MAX must be so
    large that a 16-bit int needs to use all bits as value or sign bits, but
    a 32-bit int is allowed to have (e.g.) 30 value bits, one sign bit, and
    one trap bit.
    No. It means "the value is undefined and may be illegal". It does not
    mean "the value _must_ be illegal"; it does not mean "the value _cannot_
    be illegal"; it means "you do not know whether the value is legal or
    not".

    Richard
     
    Richard Bos, Jun 18, 2004
    #15
  16. Sourcerer

    Dan Pop Guest

    This is an excellent example of trap representation vis-a-vis integers.
    This is not necessarily true. Even if all the bits are actually used
    by the representation, the standard allows -0 for one's complement and
    sign-magnitude to be a trap representation, as well as the representation
    with the sign bit set and all the value bits reset for two's complement
    (normally, this is corresponding to type_MIN).
    According to the standard, it is an unspecified value, and this includes
    trap representations.
    All the trap representations not involving padding bits (bits that do not
    contribute to the value) have already been described above. Once you
    have padding bits, they can have the effect you have already explained.

    Dan
     
    Dan Pop, Jun 18, 2004
    #16
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.