Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying one structure to another

Tags:

c

copy

struct

I know that I can copy the structure member by member, instead of that can I do a memcpy on structures?

Is it advisable to do so?

In my structure, I have a string also as member which I have to copy to another structure having the same member. How do I do that?

like image 823
asir Avatar asked Feb 08 '11 08:02

asir


People also ask

How do you copy from one structure to another structure?

memcpy (dest_struct, source_struct, sizeof (*dest_struct)); dest_struct->strptr = strdup (source_struct->strptr); This will copy the entire contents of the structure, then deep-copy the string, effectively giving a separate string to each structure.

What is a copy structure?

Structure copies are done the same way no matter how you indicate the structures. For example, PairOfInts *p, *q; p = new PairOfInts; q = new PairOfInts; p->a = 20; p->b = 40; *q = *p; copies structure *p into *q.

Can we copy struct in C?

In C/C++, we can assign a struct (or class in C++ only) variable to another variable of same type. When we assign a struct variable to another, all members of the variable are copied to the other struct variable.


3 Answers

Copying by plain assignment is best, since it's shorter, easier to read, and has a higher level of abstraction. Instead of saying (to the human reader of the code) "copy these bits from here to there", and requiring the reader to think about the size argument to the copy, you're just doing a plain assignment ("copy this value from here to here"). There can be no hesitation about whether or not the size is correct.

Also, if the structure is heavily padded, assignment might make the compiler emit something more efficient, since it doesn't have to copy the padding (and it knows where it is), but mempcy() doesn't so it will always copy the exact number of bytes you tell it to copy.

If your string is an actual array, i.e.:

struct {   char string[32];   size_t len; } a, b;  strcpy(a.string, "hello"); a.len = strlen(a.string); 

Then you can still use plain assignment:

b = a; 

To get a complete copy. For variable-length data modelled like this though, this is not the most efficient way to do the copy since the entire array will always be copied.

Beware though, that copying structs that contain pointers to heap-allocated memory can be a bit dangerous, since by doing so you're aliasing the pointer, and typically making it ambiguous who owns the pointer after the copying operation.

For these situations a "deep copy" is really the only choice, and that needs to go in a function.

like image 112
unwind Avatar answered Sep 21 '22 09:09

unwind


Since C90, you can simply use:

dest_struct = source_struct; 

as long as the string is memorized inside an array:

struct xxx {     char theString[100]; }; 

Otherwise, if it's a pointer, you'll need to copy it by hand.

struct xxx {     char* theString; };  dest_struct = source_struct; dest_struct.theString = malloc(strlen(source_struct.theString) + 1); strcpy(dest_struct.theString, source_struct.theString); 
like image 35
Simone Avatar answered Sep 20 '22 09:09

Simone


If the structures are of compatible types, yes, you can, with something like:

memcpy (dest_struct, source_struct, sizeof (*dest_struct));

The only thing you need to be aware of is that this is a shallow copy. In other words, if you have a char * pointing to a specific string, both structures will point to the same string.

And changing the contents of one of those string fields (the data that the char * points to, not the char * itself) will change the other as well.

If you want a easy copy without having to manually do each field but with the added bonus of non-shallow string copies, use strdup:

memcpy (dest_struct, source_struct, sizeof (*dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);

This will copy the entire contents of the structure, then deep-copy the string, effectively giving a separate string to each structure.

And, if your C implementation doesn't have a strdup (it's not part of the ISO standard), get one from here.

like image 29
paxdiablo Avatar answered Sep 20 '22 09:09

paxdiablo