24

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

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().

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

olliezhu
  • 752
  • 1
  • 8
  • 17

5 Answers5

36

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. 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 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.

There are, however, cases where only memcpy works. 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.
  • 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 may be more efficient to do a single memcpy rather than looping and copying the structures individually. Then again, it may not. It's hard to say, memcpy implementations 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.

Note also that although in C memcpy and structure assignment are usually equivalent, in C++ memcpy and structure assignment are not equivalent. 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.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Cool, thanks. Sorry about the deep/shallow copy confusion. I was under the impression that a shallow copy was like a pointer assignment, like `b1 = b0` instead of `*b1 = *b0`. – olliezhu Nov 08 '12 at 07:09
7

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.

From Arm site:

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.

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

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • 2
    Shouldn't the compiler take care of everything being aligned properly? – alk Nov 08 '12 at 07:07
  • 2
    @alk, the compiler assumes everything is aligned properly, as this allows significant performance improvements on many platforms. If you just use malloc to allocate memory for your structure, it will make sure it's aligned, but if you start doing pointer arithmetic or reading structures from the file or network this is no longer the case and the compiler's assumptions may be violated, causing undefined behavior. Note that you won't see this on x86 as most x86 operations handle unaligned accesses transparently, with a slight performance hit. – bdonlan Nov 08 '12 at 07:16
  • @bdonlan Fair enough I see the issues related to reading/writing from/to propably badly aligned I/O-buffers. Anyhow why there should be problems using (properly typed) pointer arithmetics I do not get, as the compiler should know anything needed (at compile time) to generate the correct code. – alk Nov 08 '12 at 07:42
  • 1
    @alk exactly. As long as you play by the rules, everything is aligned. Once you start casting pointers to `char *`, adding offsets, and casting them back, the compiler no longer knows what's going on. – bdonlan Nov 09 '12 at 04:56
  • "The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated" -- C99 §7.20.3 So alignment is a non issue here and `memcpy` is no better or worse than structure assignment (except being more error prone). – Craig Barnes Apr 19 '18 at 15:56
6

I'm resurrecting this old question because the answers do not explain why memcpy is actually preferred.

memcpy is preferred because it makes it clear the programmer wants to copy the content and not simply the pointers.

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:

memcpy(s1,s2,sizeof(s1));
  • In a recent discussion, a colleague maintained that struct assignment was more type safe and thus better. I like your answer, but don't know what to think of my colleague's argument. I suppose both sides have merits. – Thagomizer Jan 13 '20 at 21:23
0

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.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
-2

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.