[英]Copying structure in C with assignment instead of memcpy()
直到最近,我才看到用memcpy()
复制结构字段。 在类和在线指令中,将一个结构的内容复制到另一个结构中通常看起来像
struct block *b0 = malloc(sizeof(struct block));
struct block *b1 = malloc(sizeof(struct block));
/* populate fields in *b0 */
memcpy(b1, b0, sizeof *b1); /* copy contents of b0 into b1 */
/* free b0, b1 */
但是,也可以通过替换memcpy()
的简单赋值来完成此任务。
*b1 = *b0; /* dereferenced struct assignment */
有没有充分的理由说明为什么它没有被广泛使用(至少在我有限的经验中)? 这两个方法 - 赋值和memcpy()
等价,还是有一些令人信服的理由一般使用memcpy()
?
两种方法都是等效的,并执行浅拷贝 。 这意味着复制了结构本身,但不复制结构引用的任何内容。
至于为什么memcpy
更受欢迎,我不确定。 较旧版本的C不支持结构分配( 虽然它早在1978年就是常见的扩展 ),因此memcpy样式可能会成为制作更多可移植代码的方式吗? 在任何情况下,PC编译器都广泛支持结构分配,并且使用memcpy
更容易出错(如果大小错误,可能会发生坏事),因此最好尽可能使用结构分配。
但是,只有memcpy
有效。 例如:
memcpy
,因为结构分配需要正确对齐源和目标。 memcpy
,并将此附加信息计入大小字段。 memcpy
可能更有效,而不是单独循环和复制结构。 然后,它可能不会。 很难说, memcpy
实现的性能特征不同。 还要注意,虽然在C memcpy
和结构赋值中通常是等价的,但在C ++中memcpy
和结构赋值并不等价。 在一般的C ++中,最好避免使用memcpy
结构,因为结构赋值可以并且经常被重载以执行其他操作,例如深层复制或引用计数管理。
这可能不是您寻找的确切答案。
我解释了我遇到的情景。
当我们使用memcpy()
,它会逐字节地复制到目标。 所以不用担心ARM架构中的数据对齐。 如果使用=
运算符,并且任何一个地址未与4字节对齐,则会出现对齐错误。
来自Arm站点:
指向目标位置的指针,该指针位于写入的最后一个字节之外一个字节。 这使得写入过程的继续with perfect alignment of bytes
用于字符串串联内存块with perfect alignment of bytes
。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0175k/Cihbbjge.html
我正在复活这个老问题,因为答案并没有解释为什么 memcpy
实际上是首选。
memcpy
是首选,因为它清楚地表明程序员想要复制内容而不是简单的指针。
在下面的示例中,两个赋值有两个非常不同的东西:
struct Type *s1,*s2;
*s1=*s2;
s1=s2;
无意中使用一个而不是另一个可能会产生灾难性的后果。 编译器不会抱怨。 除非在使用未初始化指针时程序崩溃,否则错误很长时间都会被忽视并产生奇怪的副作用。
将其写成以下之一:
memcpy(s1,s2,sizeof(*s1));
memcpy(s1,s2,sizeof(*s2));
memcpy(s1,s2,sizeof(struct Type));
让读者知道目的是复制内容(以类型安全和边界检查为代价)。
有些编译器(例如gcc)甚至会在遇到类似以下内容时发出有关sizeof的警告:
memcpy(s1,s2,sizeof(s1));
有些人更喜欢memcpy,因为这是他们学到的东西,他们从来没有想过他们可以做一个任务(在古代,不允许任务,但很久以前)。 没有对齐问题需要担心,因为malloc()分配的内存总是正确对齐。 而且由于编译器可以将这个赋值简单地转换为memcpy调用,因此它永远不会比memcpy更慢或更多代码。 当然,嵌入式系统中存在严重过时的编译器。
在嵌入式平台上工作的人更愿意使用memcopy而不是直接分配结构。 主要是当您处理嵌入式平台时,某些编译器不支持直接结构分配,因为您需要使用memcopy。 如果您正在使用PC,那么在任何一种情况下都没有问题,两者都是有效的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.