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

时间:2015-01-07 23:55:53

标签: c arrays pointers memory memcpy

在下面的示例中,我有一个3D数组,我将其传递给一个函数," fun",但只传递一个"切片" 3D阵列的一部分,即2D阵列。在函数中,我有另一个2D变量,它在double for循环中取一些值。在退出函数之前,我需要将2D临时数组复制到" slice"的3D阵列。我尝试了以下方法,但我对memcpy的使用是"销毁"功能外的原始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

}
编辑:我想添加&#34;数组&#34;具有

的尺寸
array[TDIM][YDIM][XDIM]

和&#34; tmp&#34;具有

的尺寸
tmp[YDIM][XDIM]

我在评论中确实解决了这个问题,但我想我应该在主要问题中指出它。我还表明我在函数中释放了tmp的记忆。

编辑2:我包括&#34; allocate3D&#34;和&#34; deallocate3D&#34;用于进一步分析存储器的功能。

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);
}

功能&#34; allocate2D&#34;和&#34; deallocate2D&#34;遵循相同的概念,减去&#34; TDIM&#34;维度,所以为了简单起见,我会把它留下来。引起我的注意的是,我试图使用&#34; memcpy&#34;可能不是连续的,并且是#34;锯齿状的&#34;。除了提供分配功能外,是否有一种简单的方法来识别连续的内存存储? 3D数组如何存储在内存中?

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

2 个答案:

答案 0 :(得分:1)

我认为你想在fun做的事情是:

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

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

我假设你的维度是正确的(你没有张贴allocate3d的正文以便无法验证)

答案 1 :(得分:0)

我不确定你需要一个临时数组。由于您已经传入了数组本身,因此在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;
        }
    }
}

让我知道它是怎么回事!