【问题标题】:Shift elements by one index with memmove使用 memmove 将元素移动一个索引
【发布时间】:2018-06-07 14:21:43
【问题描述】:

我正在尝试将动态创建的 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*));

谁能给我一个提示?

【问题讨论】:

  • 您需要发布minimal, complete, and verifiable example 看看我们可以看到您正在使用什么。您可以通过多种方式实现vector
  • 如果是动态分配的,第一个维度应该是一个指针数组。为什么不只是移动这些指针,而不是移动所有数据?

标签: c multidimensional-array memmove


【解决方案1】:

只需这样做即可(以 3d 数组说明)

memmove(arr[1], arr[0], Y*Z*sizeof(int));

其中YZ 表示二维数组的其他二维。

这里arr[X][Y][Z]int 数组,其中X&gt;=2

在动态分配内存的情况下,您需要一个接一个地处理每个连续的块。然后它会工作。

【讨论】:

  • 这会产生与我的问题中的 memmove 相同的结果
  • @Schueni1.: 这就是方法。提供更多上下文。
【解决方案2】:

使用更高的优化级别 (-O3) 进行编译。获得对vector-&gt;arr 的直接引用,而不是强制取消对每个数组访问的引用。

假设您将arr 分配为连续内存,您对memmove 的调用看起来正确了一半。不过,既然你说的是“动态”,那我就很怀疑了。加上大小计算似乎非常错误,sizeof(int*)

我想arr 不是int arr[constexpr][constexpr][constexpr](单个,连续分配),而是int ***arr

在这种情况下,memmove 会出现严重错误。在将arr 字段的int** 内容移动了一个(实际上已经进行了移动)之后,它导致了堆上令人讨厌的溢出,很可能偶然也命中了大部分int* 分配。

看起来像一个双重移动,并留下一个完全被破坏的堆。

【讨论】:

    【解决方案3】:

    当你像这样创建一个动态多维数组时,数组内容是不连续的——每一行都是一个单独的分配。所以你不能用一个memmov()来移动它。

    但不需要复制所有数据,只需将顶层数组中的指针移位即可。

    int **temp = arr[l-1]; // save last pointer, which will be overwritten
    memmov(&arr[1], &arr[0], sizeof(*arr[1]));
    arr[0] = temp;
    

    我已将最后一个元素移动到第一个元素,以避免两个元素指向相同的数据。您还可以释放旧的最后一个元素(包括释放它指向的数组)并创建一个新的第一个元素,但这更简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-27
      • 2010-11-19
      • 2013-09-01
      相关资源
      最近更新 更多