我试图将动态创建的3d数组中的元素移动一个索引,以便每个元素[i][j][k]
都在[i+1][j][k]
上。
这就是我的数组创建方式
typedef struct stencil{
int ***arr;
int l;
int m;
int n;}matrix;
void createMatrix(matrix *vector){
vector->arr = (int***) malloc(sizeof(int**) * (vector->l+2));
for (int i = 0; i< vector->l+2; ++i) {
vector->arr[i] = (int**) malloc(sizeof(int*) * (vector->m+2));
for (int j = 0; j < vector->m+2; ++j) {
vector->arr[i][j] = (int*) calloc((vector->n+2),sizeof(int));
}
}
}
这基本上是我想用memmove
实现的for(int i = vector->l-1; i >= 0; --i){
for(int j = vector->m; j >= 0; --j){
for(int k = vector->n; k >= 0; --k){
vector->arr[i+1][j][k] = vector->arr[i][j][k];
}
}
}
由于某种原因,memmove转移2个指数。
memmove(&(vector->arr[1][1][1]), &(vector->arr[0][1][1]), (vector->l+2)*(vector->m+2)*(vector->n)*sizeof(int*));
有人能给我一个提示吗?
答案 0 :(得分:2)
当您创建这样的动态多维数组时,数组内容不是连续的 - 每行都是单独的分配。所以你不能用一个memmov()
来移动它。
但是你不需要复制所有数据,只需移动顶层数组中的指针。
int **temp = arr[l-1]; // save last pointer, which will be overwritten
memmov(&arr[1], &arr[0], sizeof(*arr[1]));
arr[0] = temp;
我已将最后一个元素移动到第一个元素,以避免有两个指向相同数据的元素。你也可以释放旧的最后一个元素(包括释放它指向的数组)并创建一个新的第一个元素,但这更简单。
答案 1 :(得分:1)
简单地执行此操作(在3d数组中进行说明)
memmove(arr[1], arr[0], Y*Z*sizeof(int));
其中Y
和Z
表示2d数组的其他2维。
此处arr[X][Y][Z]
是int
数组X>=2
。
在动态分配内存的情况下,您需要逐个执行每个连续的块。然后它会工作。
答案 2 :(得分:1)
使用更高的优化级别(-O3
)进行编译。获取vector->arr
的直接引用,而不是强制解除对每个阵列访问的依赖。
在假设您将memmove
分配为连续内存的情况下,您对arr
的调用看起来是正确的。但是,既然你说“动态”,我非常怀疑。加上sizeof(int*)
我认为arr
不是int arr[constexpr][constexpr][constexpr]
(单一,连续分配),而是int ***arr
。
在这种情况下,memmove
出现了可怕的错误。将int**
字段的arr
内容移动一个(实际上已经移动了)之后,它在堆上引起了一个令人讨厌的溢出,很可能是偶然命中{{1以下分配。
看起来像是一个双重移动,并留下了一个完全被破坏的堆。