结构体赋值还是 memcpy?

53

如果我想在C语言中将一个结构体复制到另一个结构体,以下做法的优缺点是什么:

struct1 = struct2;

vs

的翻译是:vs。
memcpy(&struct1, &struct2, sizeof(mystruct_t));

它们是否等效?性能或内存使用上是否有差异?


4
在结构体内要小心内存分配。例如,如果您有一个包含指向字符串的指针的结构体,并为该字符串分配了内存,则不会复制该内存。内存的指针会被复制,但是内存本身不会被复制。换句话说,这种类型的赋值不是深拷贝。使用vanilla memcpy也不是深拷贝。这可能会让人困惑,不知道谁拥有分配的内存。 - Pemdas
我认为这个问题更适合在 Stackoverflow 上提问。 - karlphillip
2
我认为这个问题已经在这里得到了很好的回答:https://dev59.com/f2445IYBdhLWcg3wTIjm - karlphillip
4个回答

52
struct1=struct2; 表示不仅更加简洁,而且更短,同时给编译器留下了更多的优化机会。 = 的语义是赋值,而 memcpy 只是复制内存。这在可读性上有很大的区别,尽管在这种情况下 memcpy 做的是相同的事情。

使用=


3
结构体 s 和结构体指针 s 之间存在一个主要问题,两者都可以通过 equals 函数很好地工作,因此在阅读时无法看出它们之间的区别。s 给出的是相同结构体的引用(地址),而 struct s 给出的是结构体的副本。当需要使用 deallocate(s) 时,只有使用相同的 struct * s 才能正常工作;但如果你愚蠢地只使用 struct s 的 dealloc,那么 mystruct 就会有内存泄漏问题。同时,使用指针也更快速。只需牢记你所做的事情,就应该没问题了。视情况而定。 - DragonLord

3

我不确定性能差异,尽管我猜测大多数编译器都会在底层使用memcpy。

在大多数情况下,我更喜欢赋值操作,它更易于阅读,并且更加明确其目的。想象一下,如果你更改了任何一个结构体的类型,编译器将引导你进行必要的更改,要么给出编译器错误,要么使用operator=(如果存在)。而第二种方法则可能会盲目复制,从而导致微妙的错误。


3
请查看关于同一主题的对话:http://bytes.com/topic/c/answers/670947-struct-assignment 基本上,在该线程中,有很多关于结构体复制的边角情况存在争议。如果结构体的所有成员都是简单值(int、double等),那么情况就非常清晰。混乱出现在数组和指针以及填充字节的处理上。
对于memcpy,每个字节都是逐字复制的,这包括绝对内存指针、相对偏移量等等,应该很清楚。

2

没有固有的原因说明哪个性能更好。不同编译器及其版本可能会有所不同,所以如果您真的关心性能,就需要进行性能分析和基于事实的基准测试来做决策。

直接赋值更易于阅读。

与赋值相比,赋指针给结构体稍微有点风险,因为您可能会将指针分配给结构体而不是指向结构体的指针。如果您担心这一点,您可以确保您的单元测试覆盖了这一点。我不会担心这种风险。(同样,memcpy也存在风险,因为您可能会错误地获取结构体的大小。)


如果您使用sizeof和正确的结构体,那么memcpy就没有任何风险。我想,如果您选择了错误的结构体,那么就会出现错误。不过,最终您可能会遇到分段错误。 - Michael K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接