C++使用memcpy拷贝地址数组优化指针移位函数的问题求助
问题修正说明
核心错误点
- 源地址类型错误:你调用
memcpy时传入的源是in+i*helper,类型为T*,指向的是in数组中存储的T类型元素值,memcpy会直接把这部分元素的二进制内容当做指针值复制到out数组,自然出现「元素值直接转换为指针」的错误。你的需求是存储指向in元素的地址,而in数组本身没有存储这些地址,不存在现成的连续内存块供你直接拷贝。 - 偏移计算逻辑错误:新函数中
pos + i < size的判断、以及out的偏移计算完全不符合原函数的循环移位逻辑,原函数的本质是将&in[0]到&in[size-1]的指针序列循环左移k = (pos-1)*size/dist位,新函数的分块拷贝逻辑和原逻辑不匹配。
优化建议
原函数的逻辑非常简单,开启O2编译优化后,编译器会自动对循环做向量化优化,执行效率远高于你手动实现memcpy的版本。如果希望进一步优化可以直接简化原函数的分支判断:
template <typename T> T** shifting (T* in, int size, int dist, int pos) { auto out = new T* [size]; int k = (pos-1) * size / dist; for (int i = 0; i < size; ++i) { // 用模运算替代分支,更利于编译器优化 out[i] = in + (i + k) % size; } return out; }
如果你一定要用内存拷贝实现,需要先构造存储所有in元素地址的临时数组,再分两次memcpy到out中,但这种方案会额外申请和释放临时数组,实际性能反而不如直接循环:
template <typename T> T** stuff(T* in, int size, int dist, int pos) { int k = (pos-1) * size / dist; auto out = new T* [size]; // 构造临时指针数组 auto tmp = new T* [size]; for (int i = 0; i < size; ++i) { tmp[i] = in + i; } // 分两次拷贝完成循环移位 memcpy(out, tmp + k, (size - k) * sizeof(T*)); memcpy(out + (size - k), tmp, k * sizeof(T*)); delete[] tmp; return out; }
内容的提问来源于stack exchange,提问作者Raumschifffan
相关产品推荐
相关产品推荐

