C++中如何快速将结构体数组的单个成员复制到对应类型数组?
首先明确:没法用memcpy这类直接内存拷贝的方式实现。原因很简单——结构体里的member2在内存中不是连续存储的。以你给出的MyStruct为例,member1是8字节的double,member2是4字节的unsigned int,结构体对齐后大小通常是16字节(按8字节对齐规则)。这意味着每个arStructs[i].member2之间隔了16字节的内存(下一个member2的地址是当前member2地址+16),中间夹杂着member1的内容和对齐填充的字节,完全不是连续的内存块,而memcpy只能处理连续的内存区域。
不过你不用担心性能,下面几种方案可以让复制效率拉满:
依赖编译器优化的手动循环
你写的遍历循环看似简单,但开启O2/O3级别的编译优化后,编译器会自动对循环做展开、向量化等优化,生成的代码效率几乎和连续内存拷贝无异。完全不用纠结手动循环的“低效”,现代编译器的优化能力远超想象。用标准库算法简化代码
如果你觉得手动循环不够优雅,可以用std::transform来实现,代码更简洁,性能和手动循环完全一致(编译器同样会优化):#include <algorithm> std::transform(std::begin(arStructs), std::end(arStructs), std::begin(arUnsignedInts), [](const MyStruct& s) { return s.member2; });调整数据结构(如果允许的话)
要是你能提前调整数据存储方式,把同类型成员打包成数组,就能直接用memcpy了:struct MyData { double member1[size]; unsigned int member2[size]; }; MyData data; unsigned int arUnsignedInts[size]; // 直接复制连续的member2数组 memcpy(arUnsignedInts, data.member2, size * sizeof(unsigned int));这种“数组的结构体”替代“结构体的数组”的方式,适合那些需要频繁单独访问某类成员的场景,但前提是你能修改初始的数据结构设计。
总的来说,不用执着于memcpy,在不能调整数据结构的情况下,优化后的循环或std::transform就是最高效的方案。
内容的提问来源于stack exchange,提问作者Anthony Bruce

