You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:54:08