我有这个StructType st = StructTypeSecondInstance->st;
,它会产生一个段错误。奇怪的是,堆栈回溯告诉我:
0x1067d2cc: memcpy + 0x10 (0, 10000, 1, 1097a69c, 11db0720, bfe821c0) + 310
0x103cfddc: some_function + 0x60 (0, bfe823d8, bfe82418, 10b09b10, 0, 0) +
那么,struct assigment是否使用memcpy
?
答案 0 :(得分:5)
一个人说不出来。小结构甚至可以保存在寄存器中。是否使用memcpy
是一个实现细节(它甚至不是实现定义的,或者未指定 - 它只是编译器编写者选择并且不需要的东西文档。)
从C标准的角度来看,重要的是在分配之后,目标结构的struct成员比较等于源结构的相应成员。
我希望编译器编写者在速度和简单性之间进行权衡,可能基于结构的大小,使用memcpy
的可能性越大。一些memcpy
实现非常复杂,并且使用不同的算法,具体取决于长度是否为2的幂,或src和dst指针的对齐。为什么要使用内嵌版本的memcpy
重新发明轮子或炸毁代码?
答案 1 :(得分:2)
可能,是的。
这应该不足为奇:结构赋值需要尽快将一堆字节从一个地方复制到另一个地方,这恰好是memcpy()
应该擅长的事情。如果你是编译器编写者,那么生成对它的调用似乎是不费吹灰之力的。
请注意,这意味着分配具有大量填充的结构可能效率低于最佳效果,因为memcpy()
无法跳过填充。
答案 2 :(得分:1)
该标准没有说明编译器实际如何实现赋值(或任何其他运算符)。没有什么能阻止编译器(例如)为源文件中的每个操作生成一个函数调用。
编译器拥有执行任务的许可,因为它认为最佳。大多数情况下,对于大多数平台上的大多数编译器,这意味着如果结构相当小,编译器将生成内联的移动指令序列;如果结构很大,调用memcpy很常见。
然而,编译器循环生成随机位域并在其中一个与赋值源匹配时停止(让我们将此算法称为 bogocopy )将完全有效。
如果您的目标是没有可用(或完整)libc的平台,那么支持非托管操作的编译器通常会为您提供关闭以发出此类libcall的权限。
答案 3 :(得分:0)
这取决于编译器和平台。大对象的分配可以使用memcpy
。但这绝不是段错误的原因。