【问题标题】:memcpy a 3d pointer in cmemcpy c 中的 3d 指针
【发布时间】:2013-10-04 18:39:00
【问题描述】:

如何将一个 3d 指针 memcpy 指向另一个 3d?我已经尝试了以下方法:

void somefunction(ArrayBlock **** b1, int noOfBlocks, ArrayBlock **** b2){  
   memcpy((&b2), (&b1), noOfBlocks*sizeof(ArrayBlock));
}

这在 gdb 中给了我以下错误:

[Inferior 1 (process 8528) exited with code 030000000005]

b1 和 b2 都在 main 函数中分配内存,如下所示:

ArrayBlock ***b2;
b2 = malloc(max_x * sizeof(ArrayBlock **));
for (i = 0; i < max_x; ++i)                             
{
    b2[i] = malloc(max_y * sizeof(ArrayBlock *));
    for (j = 0; j < max_y; ++j)
    {
        b2[i][j] = malloc(max_z* sizeof(ArrayBlock));
    }
}


解决方案:

我想因为我的 3D 指针(数组)的初始化是不连续的,一个 memcpy 是不够的。

这就是我所做的:

int i2, j2;
for(i2 = 0; i2 < max_x; i2++){
  for(j2 = 0; j2 < max_y; j2++){
    memcpy(&(*b2)[i2][j2][0], &(*b1)[i2][j2][0], max_z*sizeof(ArrayBlock));
  }
}

我认为这一次真的很有效,感谢那些帮助过我的人。

【问题讨论】:

  • 因为没有“3D 指针”之类的东西。有 3D 数组和指针对指针的指针,它们并不相同。 [见此](c-faq.com/aryptr/aryptr2.html)。
  • 看在上帝的份上,你为什么要通过***
  • 您是否意识到&amp;b1 检索局部变量的地址,而不管您将什么传递给该函数?
  • 以这种方式分配 3D 数组(最常见的一种),不,它不会工作,因为包含实际值的缓冲区不连续。
  • 不,不要记忆指针!如果你必须 memcpy 指针,你做错了什么。这将导致两个数组共享这些指针,并在您尝试释放数组时引发一场史诗般的大风暴。

标签: c pointers memcpy


【解决方案1】:

这取决于您的 3D 数组是如何分配的,但在最常见的情况下(数组数组的数组)答案是否定的。

一种分配 3D 数组的方法,但是:

  • 分配单个 CX*CY*CZ 数组的 Stuffs (Stuff* pXyz)
  • 将单个 CX*CY 指针数组分配给 Stuff (Stuff** ppXy)
  • 使用指向pXyz (ppXy[x*CY + y] = &amp;pXyz[x*CY*CZ + y*CZ + 0];) 各个区域的指针对其进行初始化
  • 将单个 CX 指针数组分配给指向 Stuff 的指针 (Stuff*** pppX)
  • 使用指向ppXy (pppX[x] = &amp;ppXy[x*CY + 0];) 各个区域的指针对其进行初始化
  • return pppX;

我希望我没有弄错这些,但这是基本思想:一维,一个 malloc。

Stuff*** Alloc3DArray(size_t cx, size_t cy, size_t cz) {
    Stuff*** ret = NULL;

    /*Allocate a single CX*CY*CZ array of Stuffs*/
    Stuff* pXyz = malloc(cx * cy * cz * sizeof(*pXyz));
    if(pXyz!=NULL) {
        /*Allocate a single CX*CY array of pointers to Stuff*/
        Stuff** ppXy = malloc(cx * cy * sizeof(*ppXy));
        if(ppXy!=NULL) {
            /*Allocate a single CX array of pointers to pointers to Stuff*/
            Stuff*** pppX = malloc(cx * sizeof(*pppX));
            if(pppX!=NULL) {

                /*Initialize ppXy with pointers to various areas of pXyz*/
                size_t x, y;
                for(x=0 ; x<cx ; x++){
                    for(y=0 ; y<cy ; y++){
                        ppXy[x*cy + y] = &pXyz[x*cy*cz + y*cz + 0];
                    }
                }

                /*Initialize pppX with pointers to various areas of ppXy*/
                for(x=0 ; x<cx ; x++){
                    pppX[x] = &ppXy[x*cy + 0];
                }

                /*Success!*/
                ret = pppX;
            } else {
                /*Allocating third level failed: free first and second levels*/
                free(ppXy), ppXy=NULL;
                free(pXyz), pXyz=NULL;
            }
        } else {
            /*Allocating second level failed: free first level*/
            free(pXyz), pXyz=NULL;
        }
    }
    return ret;
}

有了这个,你可以memcpy这个:

memcpy(&pppDest[0][0][0], &pppSource[0][0][0], CX*CY*CZ*sizeof(***pppDest));

补充:当你完成了数组,如果你做对了,它就可以被释放:

void Free3DArray(Stuff ***pppArr) {
    if(pppArr != NULL) {
        free(**pppArr); /*Free third level*/
        free( *pppArr); /*Free second level*/
        free(  pppArr); /*Free first level*/
    }
}

【讨论】:

  • 所以这意味着我应该一次memcpy一个元素?
  • @user2847666 你想复制指针还是整个数组?
  • 我只想将一个指针的值复制到另一个。我不想复制地址,因为 b1 稍后会更改,但 b2 不应该。
  • 我按照你说的做了,我不再报错了,我会测试一下内容尽快恢复!
  • @Medinoc 请注意,这个答案是一个可怕的建议。如果需要一个 3D 数组,那真的需要T (*arr)[y][z] = malloc(x * sizeof *arr);
猜你喜欢
  • 2017-09-10
  • 1970-01-01
  • 2021-08-11
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
  • 2016-09-02
相关资源
最近更新 更多