使用 memcpy 复制地址内存

Copying memory of adresses with 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) {
        if (i+k >= size) {
            out[i] = &in[k+i-size];
        } else {
            out[i] = &in[k+i]
        }
    }
    return out;
}

这个函数正在创建一个指针数组 out 指向数组 in 的元素,以特定的顺序,我想知道是否会有一种更快的内存操作方法,所以我尝试了一些不同的方法。

新函数:

template <typename T>
T** stuff(T* in, int size, int dist, int pos) {
    int helper = size/dist;
    auto out = new T* [size];
    for (int i{0}; i < dist; i++) {
        if (pos + i < size) {
            memcpy(out + i - pos + dist, in+i*helper, helper * sizeof(T*));
        } else {
            memcpy(out + i - pos, in+i*helper, helper * sizeof(T*));
        }
    }
    return out;
}

然而,这不是给出地址数组,而是将地址后面的值转换为指针,因此我将元素的值作为指针获取。 仔细检查后,这种行为不应该是其他情况,但我想不出一种方法让它起作用。

感谢您的帮助。

你的新循环体(在你编辑之前,但我的分析基本保持不变)是:

memcpy(out + i - pos + (pos + i < size ? dist: 0), in+i*helper, helper * sizeof(T*));

扩展它以提高可读性(这不会​​影响性能,所以你也应该这样做):

T** dest = out + i - pos + (pos + i < size ? dist: 0);
T* src = in + i * helper;
memcpy(dest, src, helper * sizeof(T*));

通过类型写出来,现在你可以看到类型不兼容(T**和T*)。您要做的是将地址复制到 in 的特定位置,但您不能像这样以块的形式执行此操作,因为这些地址在内存中还不以数字形式存在,您需要创建它们!

您最好的选择是坚持使用您的原始代码,这样更清晰。如果存在性能问题,请告诉我们您正在编译的优化级别,您使用的输入大小是多少,此功能花费的时间是多少,您的时间预算是多少?

我不知道这是否正是您要查找的内容,但这 运行 会更快一些并且更容易阅读和推理。

template <typename T>
T** shifting (T* in, int size, int dist, int pos) {
    auto out = new T* [size];
    int k = (pos-1) * size/dist;

    int i, j;
    for (i = 0, j = k; i < size - k; ++i, ++j)
        out[i] = &in[j];

    for (j = 0; i < size; ++i, ++j)
        out[i] = &in[j];

    return out;
}

我终于找到了解决方案。

'simplifying' 数据类型的结构 e。 G。 int (*) [3] -> int(注:t* (*) [n] -> t*):

template <typename t> struct rip {
    typedef t type;
};
template <typename t, size_t n> struct rip <t (*) [n]> {
    typedef t type;
};

实际函数:

template <typename pArr>
pArr shift(pArr pa_in, size_t pos, size_t spl) {
    typedef typename rip<pArr>::type t;

    size_t b_in{sizeof(*pa_in)};
    size_t b_spl{b_in/spl};
    size_t n_spl{b_spl/sizeof(t)};

    auto pa_out{(pArr)malloc(b_in)};
    auto p_out{(t*)pa_out};
    auto p_in{(t*)pa_in};

    size_t i, k;
    for (i = 0, k = pos; k < spl; i++, k++)
        memcpy(p_out + i*n_spl, p_in + k*n_spl, b_spl);
    for (i = pos, k = 0; i < spl; i++, k++)
        memcpy(p_out + i*n_spl, p_in + k*n_spl, b_spl);

    return pa_out;
}

注意:pArr 需要类型 t (*) [n](例如 int* (*) [10]