使用 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]
)
基函数:
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]
)