Copying structure members

前端 未结 4 1191
既然无缘
既然无缘 2021-01-28 04:46

I am more confused with structures. There are many ways to copy a structure.

struct complex
{
   int real;
   int imaginary;
};

Assume c1 is complex structure v         


        
相关标签:
4条回答
  • 2021-01-28 05:17

    Of course the only sane way is to use assignment:

    c1 = *c2;
    

    It's true that the actual numerical value of c2, a pointer to a structure, is the same as the address of the first member. But that't doesn't matter. The types of the values involved in the assignment are both struct complex, that is what the assignment is working with and all needed bits will be copied.

    Do not use memcpy() to copy a structure, there is absolutely no point! It can in fact be a net negative, since th structure can contain padding which the assignment operator (being an operator, whose code generation is controlled by the compiler for this specific usage) can deal with and skip over, saving time. The function memcpy() has no idea of the padding of course, it's job is to copy all bytes and that's what it will do.

    Also, of course, do not use memcpy() to copy individual int-sized members. That's just ... not right, don't do that.

    Also, the assignment is higher-level, thus more abstract, and thus more compact and communicates more efficiently.

    Of course, if the structure contains pointers of its own (yours does not) you must take care to do a deep copy, and allocate new instances of the pointed-to data and copying that too. That has nothing to do with how the actual copying is done though.

    Use struct assignment. Always.

    0 讨论(0)
  • 2021-01-28 05:17

    Changing the order of structure members has no effect in this case. Struct fields are explicitly stated, as you mentioned.

    When things get more complex, it's easier to make mistakes. As you did:

    memcpy(&c1.real, &c2->real, sizeof(struct complex));
    

    It should have been:

    memcpy(&c1.real, &c2->real, sizeof(c1.real));
    

    Simpler is better:

    c1.real = c2->real;
    

    By using memcpy there is also another problem; you lose type safety. Sometimes you want that, but not usually when working with 2 entities with same data type.

    0 讨论(0)
  • 2021-01-28 05:27

    I you change the order of fields in the following way:

    struct complex
    {
        int imaginary;
        int real;
    );
    

    Then memcpy(&c1.real, &c2->real, sizeof(struct complex)) will try to copy fields starting from real and as the number of bytes you are trying to copy is the size of the whole structure it will access memory after the structure thus causing invalid memory access in some cases and in some cases it will does not produce any error. But the result of this operation is not what you expected. For ones, it will not copy the field imaginary.

    In case of you need to copy part of the structure - this is the way to do it:

    memcpy(&c1.real, &c2->real, sizeof(struct complex) - offsetof(struct complex, real));
    

    Where offsetof is a macro declared like here.

    0 讨论(0)
  • 2021-01-28 05:39

    memcpy(&c1.real, &c2->real, sizeof(struct complex)) is very strange, since bots types are atomic, there is no need for that kind of copying. Also sizeof(struct complex) is wrong, because it should have been sizeof(int) (which is only 1/2 size of the whole structure) Simple assignment is enough:

    c1.real = c2->real; 
    
    0 讨论(0)
提交回复
热议问题