c memcpy 按值结构
c memcpy struct by value
我只是想将一个结构复制到另一个结构(按值复制,而不是按引用复制)。这是完整的工作代码
/* 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;
}
这里是fiddlehttp://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变了?
请注意,在没有结构的情况下做同样的事情会按预期工作:
http://cpp.sh/6qevd
您需要复制分配的内存区域而不是结构本身
memcpy ( p2.name, p1.name, SIZE );
当你制作那个副本时,两个结构 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
是名称中的字符数加上字符串空终止符,对 realloc
的调用会更改 p2.name 的大小以匹配它。现在,保证有足够的空间,你可以memcpy
名字变成第二个。
这里使用realloc可能效率不高,因为它保留了我们不需要的p2.name的原始内容。另一种方法是先释放旧字符串,然后再为新字符串分配 space:
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 都可能失败,如果您的程序内存不足,它们将 return NULL,因此最好经常检查它。
我只是想将一个结构复制到另一个结构(按值复制,而不是按引用复制)。这是完整的工作代码
/* 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;
}
这里是fiddlehttp://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变了?
请注意,在没有结构的情况下做同样的事情会按预期工作: http://cpp.sh/6qevd
您需要复制分配的内存区域而不是结构本身
memcpy ( p2.name, p1.name, SIZE );
当你制作那个副本时,两个结构 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
是名称中的字符数加上字符串空终止符,对 realloc
的调用会更改 p2.name 的大小以匹配它。现在,保证有足够的空间,你可以memcpy
名字变成第二个。
这里使用realloc可能效率不高,因为它保留了我们不需要的p2.name的原始内容。另一种方法是先释放旧字符串,然后再为新字符串分配 space:
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 都可能失败,如果您的程序内存不足,它们将 return NULL,因此最好经常检查它。