Claudius Turner
Claudius Turner

Reputation: 65

copying part of a structure

I am trying to copy part of a large structure and I was hoping I could use pointer arithmetic to copy chunks of it at a time. So if I have the following stucture

struct {
  int field1;
  char field2;
  myClass field3;
  .
  .
  .
  myOtherClass field42;
} myStruct;
struct origionalStruct;
struct *pCopyStruct;

can I use memcpy() to copy part of it using pointer arithmetic?

memcpy(pCopyStruct, &origionalStruct.field1, 
      (char*)&origionalStuct.field1 - (char*)&origionalStuct.field23);

I know that pointer arithmetic is only valid for arrays, but I was hoping I could get around that by casting everything to (char*).

Upvotes: 1

Views: 1561

Answers (3)

too honest for this site
too honest for this site

Reputation: 12262

It would be best to put the fields you want to copy into a nested struct and just assign that to the corresponding field of the new struct. That would avoid writing, increases greatly readability and - least not last - maintains type-safety. All which memcpy does not provide.

offsetof() or using the addresses of enclosing fields would obviously not work if the copied fields are at the end or beginning of the struct.

struct {
    int field1;
    struct { char fields } cpy_fields;
} a, b;

a.cpy_fields = b.cpy_fields;

When using gcc, you can enable plan9-extensions and use an anonymous struct, but need a typedef for the inner:

typedef struct { char field1; } Inner;

struct {
    int field1;
    Inner;
} a, b;

This does not change existing code which can do: a.field2. You can still access the struct as a whole by its typename (provided you only have one instance in the outer struct): a.Inner = b.Inner.

While the first part (anonymous struct) is standard since C99, the latter is part of the plan9-extensions (which are very interesting for its other feature, too). Actually the other feature might provide an even better sulution for your problem. You might have a look at the doc-page and let it settle for a sec or two to get the implications. Still wonder why this feature did not make it into the standard (no extra code, more type-safety as much less casts required).

Upvotes: 1

fex
fex

Reputation: 307

My answer only holds for c++.

Using memcpy() to copy member variables of objects breaks encapsulation and is not good practice in general. I.e. only do that if you have very good reason. It can work if you are careful, but you are making your program very brittle: You increase the risk that future changes will introduce bugs.

E.g. also see http://flylib.com/books/en/2.123.1.431/1/

Upvotes: 1

mtijanic
mtijanic

Reputation: 2902

Yes, you can do:

memcpy(pCopyStruct, &origionalStruct.field1, 
  (char*)&origionalStuct.field23 - (char*)&origionalStuct.field1);

However, you probably want to use the offsetof() macro found in stddef.h.

memcpy(pCopyStruct, &originalStruct.field1, 
  offsetof(struct myStruct, field23)-offsetof(struct myStruct, field1));

Where if field1 is at offset 0 (first in the struct) you can omit the subtraction.

For completeness, the offsetof macro can be defined as:

#define offsetof(st, m) ((size_t)(&((st *)0)->m))

Upvotes: 0

Related Questions