Reputation: 1768
Im simply trying to copy one struct to another (copy by value, NOT by reference). Here is fully working code
/* memcpy example */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE (80*sizeof(char))
typedef struct {
char* name;
} person;
int main ()
{
person p1;
p1.name = (char*) malloc( SIZE );
person p2;
p2.name = (char*) malloc( SIZE );
// set p1
strcpy(p1.name, "John");
// copy p1 > p2
memcpy ( &p2, &p1, SIZE );
printf ("p1.name: %s (%u)\n", p1.name, &p1.name );
printf ("p2.name: %s (%u)\n", p2.name, &p2.name );
// change p1 only
printf("Changing p1.name\n");
strcpy(p1.name, "ONLY p1.name Changed");
// now, why did p2 change?
printf ("p1.name: %s (%u)\n", p1.name, &p1.name );
printf ("p2.name: %s (%u)\n", p2.name, &p2.name );
free(p1.name);
free(p2.name);
return 0;
}
Here is a fiddle http://cpp.sh/57skb
That code outputs
p1.name: John (0x791b3cdd6270)
p2.name: John (0x791b3cdd6280)
Changing p1.name
p1.name: ONLY p1.name Changed (0x791b3cdd6270)
p2.name: ONLY p1.name Changed (0x791b3cdd6280)
Expected output would be
p1.name: John (0x791b3cdd6270)
p2.name: John (0x791b3cdd6280)
Changing p1.name
p1.name: ONLY p1.name Changed (0x791b3cdd6270)
p2.name: John (0x791b3cdd6280)
Question: why does p2 change?
Note that doing the same thing without struct works as expected: http://cpp.sh/6qevd
Upvotes: 3
Views: 192
Reputation: 1862
If you just copy the struct, then you're overwriting the pointer, not what it points to. What you probably want to do instead of your memcpy is this:
size_t bytes = strlen(p1.name)+1;
p2.name = realloc(p2.name, bytes);
if (p2.name != NULL) {
memcpy(p2.name, p1.name, bytes);
}
Here, bytes
is the number of characters in the name plus the string nul-terminator, and the call to realloc
changes the size of p2.name to match it. Now, guaranteed that there's enough spoace, you can memcpy
the first name into the second.
Using realloc here is probably inefficient, because it preserves the original content of p2.name, which we don't need. An alternative would be to free the old string first, before allocating space for the new one:
size_t bytes = strlen(p1.name)+1;
free(p2.name);
p2.name = malloc(bytes);
if (p2.name != NULL) {
memcpy(p2.name, p1.name, bytes);
}
Beware that both malloc and realloc can fail, and will return NULL if your program runs out of memory, so it's good practice to always check for that.
Upvotes: 2
Reputation: 4288
When you make that copy then both structure name
member will have the same value so they point to the same memory location. Your code does not show this since you does not print the pointer value properly. Try this to see that they are indeed the same
printf ("p1.name: %s (%p)\n", p1.name, p1.name );
printf ("p2.name: %s (%p)\n", p2.name, p2.name );
Output
p1.name: John (0x3ee8d60)
p2.name: John (0x3ee8d60)
p2
does not change after strcpy(p1.name, "ONLY p1.name Changed");
. Simply p2.name
points to this new string also.
Upvotes: 3
Reputation: 67476
you need to copy the allocated memory areas not the structs itself
memcpy ( p2.name, p1.name, SIZE );
Upvotes: 1