我只是试图将一个结构复制到另一个结构(按值复制,而不是按引用复制)。这是完整的工作代码
/* 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;
}
这里是小提琴http://cpp.sh/57skb
代码输出
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)
预期输出为
p1.name: John (0x791b3cdd6270)
p2.name: John (0x791b3cdd6280)
Changing p1.name
p1.name: ONLY p1.name Changed (0x791b3cdd6270)
p2.name: John (0x791b3cdd6280)
问题:为什么p2会发生变化?
请注意,在没有struct的情况下执行相同的操作可以按预期工作:http://cpp.sh/6qevd
当您创建该副本时,两个结构name
成员将具有相同的值,因此它们指向相同的存储位置。您的代码没有显示此信息,因为您没有正确打印指针值。尝试此操作以确保它们确实相同
printf ("p1.name: %s (%p)\n", p1.name, p1.name ); printf ("p2.name: %s (%p)\n", p2.name, p2.name );
输出
p1.name: John (0x3ee8d60) p2.name: John (0x3ee8d60)
p2
在strcpy(p1.name, "ONLY p1.name Changed");
之后不改变。简单地p2.name
也指向这个新字符串。
如果仅复制该结构,则将覆盖指针,而不是其指向的指针。您可能想做的是代替memcpy的方法:
size_t bytes = strlen(p1.name)+1; p2.name = realloc(p2.name, bytes); if (p2.name != NULL) { memcpy(p2.name, p1.name, bytes); }
这里,
bytes
是名称中的字符数加上字符串nul-terminator,对realloc
的调用将更改p2.name的大小以使其匹配。现在,确保有足够的语音提示,您可以将第一个名字memcpy
改成第二个名字。在这里使用realloc可能效率不高,因为它保留了p2.name的原始内容,而我们不需要。一种替代方法是先释放旧字符串,然后再为新字符串分配空间:
size_t bytes = strlen(p1.name)+1; free(p2.name); p2.name = malloc(bytes); if (p2.name != NULL) { memcpy(p2.name, p1.name, bytes); }
请注意,如果您的程序内存不足,则malloc和realloc都可能失败,并且将返回NULL,因此,最好始终进行检查。
您需要复制分配的内存区域而不是结构本身
memcpy ( p2.name, p1.name, SIZE );