C语言 使用赋值而不是 memcpy() 在 C 中复制结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13284033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Copying structure in C with assignment instead of memcpy()
提问by olliezhu
Up until recently, I have only seen copying of structure fields done with memcpy(). In classes and online instructions, copying the contents of one struct into another generally looks like
直到最近,我才看到使用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 */
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()普遍使用?
回答by bdonlan
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 memcpyis more popular, I'm not sure. 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? In any case, structure assignment is widely supported in PC compilers, and using memcpyis 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.
至于为什么memcpy更受欢迎,我不确定。旧版本的 C 不支持结构赋值(尽管它早在 1978 年就是一个常见的扩展),所以也许 memcpy 风格作为一种制作更可移植代码的方式被卡住了?在任何情况下,PC 编译器都广泛支持结构赋值,并且使用memcpy更容易出错(如果大小错误,可能会发生坏事),因此最好尽可能使用结构赋值。
There are, however, cases where only memcpyworks. For example:
然而,有些情况下只能memcpy工作。例如:
- 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. - 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. - If you're copying an array of structures, it maybe more efficient to do a single
memcpyrather than looping and copying the structures individually. Then again, it may not. It's hard to say,memcpyimplementations differ in their performance characteristics. - 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.
- 如果您将结构复制到未对齐的缓冲区或从未对齐的缓冲区复制 - 例如,保存/加载到/从磁盘或在网络上发送/接收 - 您需要使用
memcpy,因为结构分配需要正确对齐源和目标。 - 如果您在结构之后打包附加信息,可能使用零元素数组,则需要使用
memcpy,并将此附加信息分解到大小字段中。 - 如果您要复制一个结构数组,则执行单个而不是循环和单独复制结构可能更有效
memcpy。再说一次,它可能不会。很难说,memcpy实现的性能特征不同。 - 某些嵌入式编译器可能不支持结构赋值。当然,有问题的编译器可能也不支持其他更重要的事情。
Note also that although in C memcpyand structure assignment are usually equivalent, in C++ memcpyand structure assignment are notequivalent. In general C++ it's best to avoid memcpying structures, as structure assignment can, and often is, overloaded to do additional things such as deep copies or reference count management.
还要注意,虽然在 C 中memcpy和结构赋值通常是等价的,但在 C++ 中memcpy和结构赋值并不等价。一般来说,C++ 最好避免使用memcpy结构,因为结构赋值可以并且经常被重载以执行其他操作,例如深度复制或引用计数管理。
回答by Jeyaram
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. so no worry about data alignment in ARM architecture. If you use =operator, and any one of the address is not aligned to 4-byte then alignment fault will come.
当我们使用 时memcpy(),它会逐字节复制到目的地。所以不用担心 ARM 架构中的数据对齐。如果你使用=运算符,并且任何一个地址没有对齐到 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 bytesfor string concatenation of memory blocks.
指向目标位置的指针,该位置比写入的最后一个字节高一个字节。这使得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
回答by Frédéric Marchal
I'm resurrecting this old question because the answers do not explain whymemcpyis actually preferred.
我正在复活这个老问题,因为答案并没有解释为什么memcpy实际上是首选的。
memcpyis 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));
回答by gnasher729
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). There are no alignment problems to worry about since memory allocated by malloc () is always aligned correctly. And since a compiler could trivially translate this assignment to a memcpy call, it would never be slower or more code than memcpy. Of course there are embedded systems with badly outdated compilers.
有些人更喜欢 memcpy,因为那是他们学到的东西,他们从来没有想过他们可以做一个任务(在古代是不允许的,但那是很久以前的事了)。由于 malloc() 分配的内存始终正确对齐,因此无需担心对齐问题。而且由于编译器可以轻松地将此分配转换为 memcpy 调用,因此它永远不会比 memcpy 更慢或更多代码。当然,有些嵌入式系统的编译器已经过时了。
回答by Tushar Kanani
People working on embedded platform will prefer to use memcopy instead of direct assignment of structure . Mainly when you deal with embedded platform, some compiler doesn't support direct structure assignment, for that you need to use memcopy. if you are working on pc then there is no issue in either case, Both are valid.
在嵌入式平台上工作的人更喜欢使用 memcopy 而不是直接分配结构。主要是在处理嵌入式平台时,有些编译器不支持直接结构赋值,因此需要使用memcopy。如果您在 pc 上工作,那么在任何一种情况下都没有问题,两者都是有效的。

