简体   繁体   English

使用赋值而不是memcpy()在C中复制结构

[英]Copying structure in C with assignment instead of memcpy()

Up until recently, I have only seen copying of structure fields done with memcpy() . 直到最近,我才看到用memcpy()复制结构字段。 In classes and online instructions, copying the contents of one struct into another generally looks like 在类和在线指令中,将一个结构的内容复制到另一个结构中通常看起来像

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 */

However, this task can also be accomplished by a simple assignment replacing the memcpy() . 但是,也可以通过替换memcpy()的简单赋值来完成此任务。

*b1 = *b0; /* dereferenced struct assignment */

Is there good reason why this isn't as widely used (at least in my limited experience)? 有没有充分的理由说明为什么它没有被广泛使用(至少在我有限的经验中)? Are these two methods—assignment and memcpy() —equivalent, or is there some compelling reason to use memcpy() in general? 这两个方法 - 赋值和memcpy()等价,还是有一些令人信服的理由一般使用memcpy()

Both methods are equivalent, and perform a shallow copy . 两种方法都是等效的,并执行浅拷贝 This means that the structure itself is copied, but anything the structure references is not copied. 这意味着复制了结构本身,但不复制结构引用的任何内容。

As for why memcpy is more popular, I'm not sure. 至于为什么memcpy更受欢迎,我不确定。 Older versions of C did not support structure assignment ( although it was a common extension as early as 1978 ), so perhaps the memcpy style stuck as a way of making more portable code? 较旧版本的C不支持结构分配( 虽然它早在1978年就是常见的扩展 ),因此memcpy样式可能会成为制作更多可移植代码的方式吗? In any case, structure assignment is widely supported in PC compilers, and using memcpy is more error-prone (if you get the size wrong, Bad Things are likely to happen), and so it's best to use structure assignment where possible. 在任何情况下,PC编译器都广泛支持结构分配,并且使用memcpy更容易出错(如果大小错误,可能会发生坏事),因此最好尽可能使用结构分配。

There are, however, cases where only memcpy works. 但是,只有memcpy有效。 For example: 例如:

  • If you're copying a structure to or from an unaligned buffer - eg, to save/load to/from disk or send/receive on a network - you need to use memcpy , as structure assignment requires both source and destination to be aligned properly. 如果要将结构复制到未对齐的缓冲区或从未对齐的缓冲区复制 - 例如,要保存/加载到磁盘或从网络上发送/接收 - 您需要使用memcpy ,因为结构分配需要正确对齐源和目标。
  • If you're packing additional information after a structure, perhaps using a zero-element array , you need to use memcpy , and factor this additional information into the size field. 如果要在结构之后打包附加信息(可能使用零元素数组) ,则需要使用memcpy ,并将此附加信息计入大小字段。
  • If you're copying an array of structures, it may be more efficient to do a single memcpy rather than looping and copying the structures individually. 如果要复制结构数组,那么执行单个memcpy 可能更有效,而不是单独循环和复制结构。 Then again, it may not. 然后,它可能不会。 It's hard to say, memcpy implementations differ in their performance characteristics. 很难说, memcpy实现的性能特征不同。
  • Some embedded compilers might not support structure assignment. 某些嵌入式编译器可能不支持结构分配。 There's probably other more important things the compiler in question doesn't support as well, of course. 当然,有问题的编译器可能还不支持其他更重要的事情。

Note also that although in C memcpy and structure assignment are usually equivalent, in C++ memcpy and structure assignment are not equivalent. 还要注意,虽然在C memcpy和结构赋值中通常是等价的,但在C ++中memcpy和结构赋值并不等价。 In general C++ it's best to avoid memcpy ing structures, as structure assignment can, and often is, overloaded to do additional things such as deep copies or reference count management. 在一般的C ++中,最好避免使用memcpy结构,因为结构赋值可以并且经常被重载以执行其他操作,例如深层复制或引用计数管理。

This could not be the exact answer you looking for. 这可能不是您寻找的确切答案。

Im explaining scenario which I met. 我解释了我遇到的情景。

when we use memcpy() , it does byte-by-byte copy to destination. 当我们使用memcpy() ,它会逐字节地复制到目标。 so no worry about data alignment in ARM architecture. 所以不用担心ARM架构中的数据对齐。 If you use = operator, and any one of the address is not aligned to 4-byte then alignment fault will come. 如果使用=运算符,并且任何一个地址未与4字节对齐,则会出现对齐错误。

From Arm site: 来自Arm站点:

A pointer to the destination location that is one byte beyond the last byte written to. 指向目标位置的指针,该指针位于写入的最后一个字节之外一个字节。 This enables continuation of the writing process with perfect alignment of bytes for string concatenation of memory blocks. 这使得写入过程的继续with perfect alignment of bytes用于字符串串联内存块with perfect alignment of bytes

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0175k/Cihbbjge.html http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0175k/Cihbbjge.html

I'm resurrecting this old question because the answers do not explain why memcpy is actually preferred. 我正在复活这个老问题,因为答案并没有解释为什么 memcpy实际上是首选。

memcpy is preferred because it makes it clear the programmer wants to copy the content and not simply the pointers. memcpy是首选,因为它清楚地表明程序员想要复制内容而不是简单的指针。

In the following example, the two assignments make two very different things: 在下面的示例中,两个赋值有两个非常不同的东西:

struct Type *s1,*s2;
*s1=*s2;
s1=s2;

Inadvertently using one instead of the other may have disastrous effects. 无意中使用一个而不是另一个可能会产生灾难性的后果。 The compiler won't complain. 编译器不会抱怨。 Unless the program crashes when an uninitialized pointer is used, the error can go unnoticed for a long time and produce strange side effects. 除非在使用未初始化指针时程序崩溃,否则错误很长时间都会被忽视并产生奇怪的副作用。

Writing it as one of: 将其写成以下之一:

memcpy(s1,s2,sizeof(*s1));
memcpy(s1,s2,sizeof(*s2));
memcpy(s1,s2,sizeof(struct Type));

let the reader knows that the intent is to copy the content (at the expense of type safety and bounds checking). 让读者知道目的是复制内容(以类型安全和边界检查为代价)。

Some compilers (gcc for instance) even issue a warning about the sizeof when they encounter something like: 有些编译器(例如gcc)甚至会在遇到类似以下内容时发出有关sizeof的警告:

memcpy(s1,s2,sizeof(s1));

Some people prefer memcpy because that's what they learned and they never figured out that they could just do an assignment (in ancient times the assignment wasn't allowed, but that's a long long time ago). 有些人更喜欢memcpy,因为这是他们学到的东西,他们从来没有想过他们可以做一个任务(在古代,不允许任务,但很久以前)。 There are no alignment problems to worry about since memory allocated by malloc () is always aligned correctly. 没有对齐问题需要担心,因为malloc()分配的内存总是正确对齐。 And since a compiler could trivially translate this assignment to a memcpy call, it would never be slower or more code than memcpy. 而且由于编译器可以将这个赋值简单地转换为memcpy调用,因此它永远不会比memcpy更慢或更多代码。 Of course there are embedded systems with badly outdated compilers. 当然,嵌入式系统中存在严重过时的编译器。

People working on embedded platform will prefer to use memcopy instead of direct assignment of structure . 在嵌入式平台上工作的人更愿意使用memcopy而不是直接分配结构。 Mainly when you deal with embedded platform, some compiler doesn't support direct structure assignment, for that you need to use memcopy. 主要是当您处理嵌入式平台时,某些编译器不支持直接结构分配,因为您需要使用memcopy。 if you are working on pc then there is no issue in either case, Both are valid. 如果您正在使用PC,那么在任何一种情况下都没有问题,两者都是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM