我知道我可以按成员复制结构成员,而不是我可以在结构上进行复制memcpy吗?
这样做是否明智?
在我的结构中,我有一个字符串也作为成员,我必须复制到具有相同成员的另一个结构.我怎么做?
unw*_*ind 63
通过简单赋值进行复制是最好的,因为它更短,更易于阅读,并且具有更高的抽象级别.而不是(向代码的人类读者)说"将这些位从这里复制到那里",并要求读者考虑副本的大小参数,你只是做一个简单的赋值("复制这个值来自在这里").关于尺寸是否正确,可以毫不犹豫.
此外,如果结构被大量填充,赋值可能会使编译器发出更高效的内容,因为它不必复制填充(并且它知道它在哪里),但mempcy()不是这样,它将始终复制确切的数字您告诉它复制的字节数.
如果你的字符串是一个实际的数组,即:
struct {
char string[32];
size_t len;
} a, b;
strcpy(a.string, "hello");
a.len = strlen(a.string);
Run Code Online (Sandbox Code Playgroud)
然后你仍然可以使用简单的赋值:
b = a;
Run Code Online (Sandbox Code Playgroud)
获得完整的副本.对于这样建模的可变长度数据,这不是最有效的复制方法,因为整个数组将始终被复制.
但要注意,复制包含指向堆分配内存的指针的结构可能有点危险,因为这样做会使指针混叠,并且通常会使复制操作后拥有指针的模糊不清.
对于这些情况,"深层复制"实际上是唯一的选择,并且需要进入功能.
Sim*_*one 38
从C90开始,您可以简单地使用:
dest_struct = source_struct;
Run Code Online (Sandbox Code Playgroud)
只要字符串存储在数组中:
struct xxx {
char theString[100];
};
Run Code Online (Sandbox Code Playgroud)
否则,如果它是指针,您需要手动复制它.
struct xxx {
char* theString;
};
dest_struct = source_struct;
dest_struct.theString = malloc(strlen(source_struct.theString) + 1);
strcpy(dest_struct.theString, source_struct.theString);
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 17
如果结构是兼容的类型,是的,您可以使用以下内容:
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
Run Code Online (Sandbox Code Playgroud)
您唯一需要注意的是这是一个浅层副本.换句话说,如果您char *指向特定字符串,则两个结构都将指向相同的字符串.
并且更改其中一个字符串字段的内容(char *指向而不是char *自身的数据)也将更改另一个字段.
如果您想要一个简单的副本而不必手动执行每个字段,但需要额外的非浅色字符串副本,请使用strdup:
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);
Run Code Online (Sandbox Code Playgroud)
这将复制结构的全部内容,然后深层复制字符串,有效地为每个结构提供单独的字符串.
并且,如果您的C实现没有strdup(它不是ISO标准的一部分),请从此处获取一个.
在 C 中, memcpy 只是愚蠢的冒险。只要您完全正确地获得所有三个参数,结构成员都不是指针(或者,您明确打算进行浅拷贝)并且结构中没有大的对齐间隙,memcpy 将浪费时间循环(或性能无关紧要),那么无论如何,memcpy。除了更难阅读的代码、对未来更改的脆弱性以及必须在代码审查中手动验证(因为编译器不能)之外,您一无所获,但是嘿,是的,为什么不呢。
在 C++ 中,我们前进到可笑的冒险。您可能拥有不安全的 memcpyable 类型的成员,例如 std::string,这将导致您的接收结构成为危险武器,在使用时随机破坏内存。在模拟切片副本时,您可能会遇到涉及虚函数的惊喜。优化器可以为您做一些奇妙的事情,因为它在编译 = 时保证了完整的类型知识,但对您的 memcpy 调用却无能为力。
在 C++ 中,有一个经验法则——如果你看到 memcpy 或 memset,那就有问题了。在极少数情况下这不是真的,但它们不涉及结构。当且仅当您有理由盲目复制bytes时,您才使用 memcpy 。
另一方面,赋值很容易阅读,在编译时检查正确性,然后在运行时智能地移动值。没有缺点。
您可以memcpy构造,也可以像其他任何值一样分配它们。
struct {int a, b;} c, d;
c.a = c.b = 10;
d = c;
Run Code Online (Sandbox Code Playgroud)