-3

I was wondering if there was an elegant way to copy a structure to a different structure, where the second structure is essentially the same as the original one, except without the last field(s).

For example,

struct A {
    int a;
    int b;
    int c;
};
struct B {
    int a;
};

struct A v1;
struct B v2;

Would,

memcpy(&v2, &v1, sizeof(v2));

Achieve the functionality I wish? Where v2 has the "a" value that was originally found in v1?

Thank you

  • Your sample code will read out of bounds. You will need to explain what you want to happen to the "extra" fields in `v1` – M.M Oct 12 '18 at 21:29
  • in real life it will work (once you change to sizeof(v2)) I am sure that there all sorts of standards violation though. The better / correct way is to define a union – pm100 Oct 12 '18 at 21:30
  • 1
    What's wrong with `v1.a = v2.a;`? Or, with initialization, `A v1{v2.a};? – juanchopanza Oct 12 '18 at 21:32
  • Does `v2.a = v1.a` work [for you]? You can't copy over anything else as `struct B` doesn't have the space/fields – Craig Estey Oct 12 '18 at 21:32
  • Use `sizeof(v2)`. Use the smaller struct's size so you don't access out of bounds. – Barmar Oct 12 '18 at 21:32
  • "*the second structure is essentially the same as the original one, except without the last field(s)*". This doesn't make much sense. Try: `memcpy(&v1, &v2, min(sizeof(v1), sizeof(v2)));` This will work on a wider range of structures, not only the ones in in your example (that most of the proposed solutions rely on). this could be a good candidate for inheritance. – CristiFati Oct 12 '18 at 21:33
  • Sorry I posted the wrong memcpy. The correct one should've been memcpy(&v2, &v1, sizeof(v2)); – Mitziu Echeverria Oct 12 '18 at 21:33
  • @MitziuEcheverria Edit the question if you need to correct it. – Barmar Oct 12 '18 at 21:35
  • @Barmar Thanks, I did. – Mitziu Echeverria Oct 12 '18 at 21:37
  • 1
    @juanchopanza This is a toy example. I am trying to stay away from doing that since the real structures I am dealing with have many more fields. – Mitziu Echeverria Oct 12 '18 at 21:39
  • In this toy example you should be fine, as both classes are standard layout classes so they both start with an `int`. In your actual code though it could be different. If I were you I'd present a more realistic example since there are so many edge cases. – NathanOliver Oct 12 '18 at 21:41
  • It looks like UB if `sizeof(v1) < sizeof(v2)`. – jww Oct 13 '18 at 01:10
  • You should probably show real data structures and ask a question about them. C++ and inheritance could fail if logical members `a, b, c` are in different classes on one side of the "assignment", and in one class on the other side of the "assignment". Packing could also affect the "assignment". Also, memcpy'ing bitfields is implementation defined. Also see [is it possible to do memcpy in bits instead of bytes?](https://stackoverflow.com/q/17320643/608639) – jww Oct 13 '18 at 01:13

1 Answers1

1

If instead of copying all bytes in A, you only copy the number of bytes that B expects, you will achieve your desired result:

memcpy(&v2, &v1, sizeof(v2)); // remember that the first argument is the destination

However, this is not good coding style. With this minimal code example, it is hard to tell, but you would probably want A to inherit from B so that you can convert the two without having to physically copy memory.

Otherwise, this would be easier and cleaner:

b2.a = v1.a;
mrks
  • 8,033
  • 1
  • 33
  • 62