C memcpy 2D数组到函数内的3D数组

C memcpy 2D array to 3D array within function

在下面的示例中,我有一个 3D 数组,我将其传递给函数 "fun",但仅传递 3D 数组的 "slice",即 2D 数组。在函数中,我有另一个 2D 变量,它在双 for 循环中采用一些值。在退出该函数之前,我需要将 2D 临时数组复制到 3D 数组的 "slice" 中。我尝试了以下方法,但我对 memcpy 的使用是 "destroying" 函数外的原始 3D 数组。执行此操作的正确方法是什么?

void fun(double **array, int XDIM, int YDIM);   // Declaration

int main()
{
    double ***array
    int XDIM=10,YDIM=10,TDIM=2;

    allocate3d(&array,XDIM,YDIM,TDIM); // This works fine
    fun(array[0],XDIM,YDIM);

    //
    //  Other code note important to problem here
    //

    deallocate3d(array,XDIM,YDIM,TDIM); // This works fine
}


void fun(double **array, int XDIM, int YDIM)
{
    double **tmp;

    allocate2d(&tmp,XDIM,YDIM); // This works fine

    for(int j = 0; j < YDIM; j++)
    {
        for(int i = 0; i < XDIM; i++)
        {
            tmp[j][i] = 2.5;
        }
    }

    memcpy(array,tmp,XDIM*YDIM*sizeof(double));

    deallocate2d(tmp,XDIM,YDIM); // This works fine

}

编辑:我想补充一点 "array" 的尺寸为

array[TDIM][YDIM][XDIM]

和 "tmp" 的尺寸为

tmp[YDIM][XDIM]

我确实在评论中解决了这个问题,但我认为我应该在主要问题中指出它。我还展示了我在函数中释放了 tmp 的内存。

编辑 2:我包括 "allocate3D" 和 "deallocate3D" 函数以进一步分析内存存储。

int allocate3D(double ****array, int XDIM, int YDIM, int TDIM)
{
    // Allocate 3rd dimension
    *array = calloc(TDIM,sizeof(double**));
    if (array==NULL)
    {
        printf("Error in memory allocation\n");
        return (EXIT_FAILURE);
    }

    // Allocate each 3rd dimensional pointer with array of pointers
    for(int i = 0; i < TDIM; i++)
    {
        (*array)[i] = calloc(YDIM,sizeof(double*));
    }

    if (array==NULL)
    {
        printf("Error in memory allocation\n");
        return (EXIT_FAILURE);
    }

    // Allocate remaining dimension
    for(int i = 0; i < TDIM; i++)
    {
        for(int j = 0; j < YDIM; j++)
        {
            (*array)[i][j] = calloc(XDIM,sizeof(double));
        }
    }

    if(array == NULL)
    {
        printf("Error in memory allocation\n");
        return(EXIT_FAILURE);
    }

    return 0;
}

void deallocate3D(double ***array, int XDIM, int YDIM, int TDIM)
{
    //  Deallocate each 3rd dimensional pointer
    for(int i = 0; i < TDIM; i++)
    {
        for(int j = 0; j < YDIM; j++)
        {
            free((array)[i][j]);
        }

        free((array)[i]);
    }

    // Deallocate 3rd dimension
    free(array);
}

函数 "allocate2D" 和 "deallocate2D" 遵循相同的概念,减去 "TDIM" 维度,因此为了简单起见,我将其省略。我已经注意到,我尝试与 "memcpy" 一起使用的数组部分可能不连续,而是 "jagged"。除了提供分配功能外,有没有简单的方法来识别连续的内存存储? 3D 数组如何存储在内存中?

编辑 3:我想我可能找到了线索……在上面的示例中,我设置了 YDIM == 1。我相信这会影响连续内存对齐,并且我的分配和自由函数会导致错误.我使用过 Valgrind,它会在 YDIM == 1 时标记我的分配和自由函数。此外,这会影响 memcpy 的行为方式。对我的猜测有什么想法吗?为什么设置 YDIM == 1.... 因为有时就是这种情况。我试图在应用程序中保持通用性。

我不确定您是否需要临时数组。由于您已经传入数组本身,并且在 c 中您可以直接使用其他函数修改数组。也许...

void fun(double **array, int XDIM, int YDIM)
{
    for(int j = 0; j < YDIM; j++)
    {
        for(int i = 0; i < XDIM; i++)
        {
            array[j][i] = 2.5;
        }
    }
}

让我知道进展如何!

我认为你想在 fun 中做的是:

for(int j = 0; j < YDIM; j++)
{
    for(int i = 0; i < XDIM; i++)
    {
        array[j][i] = tmp[j][i];
    }
}

您不能使用单个 memcpy,因为您的数组不是连续的内存块;它是一个 锯齿状数组(每个一维块存储在单独的分配中)。

我假设您的尺寸顺序正确(您没有 post allocate3d 的正文,因此无法验证)