3维数组内存分配

时间:2018-04-06 08:52:23

标签: c arrays memory multidimensional-array ipc

我有一个带有3D阵列内存分配的代码,名为" matrix"我通常将x,y,z方向索引为matrix[i][j][k],其中ijk分别是x,y和z方向的索引。代码中遵循的分配过程如下(lr只是double的typedef)

lr ***lr_3D_matrix(int m, int n, int o)/**  \brief create a 3D matrix with size [m, n,o] of type lr*/
{
    lr ***matrix;
    int i, j;
    matrix =  malloc(m * sizeof(lr **));    //allocate first dimension
    matrix[0] =  malloc(m * n * sizeof(lr *));  //allocate continous memory block for all elements
    matrix[0][0] = malloc(m * n * o * sizeof(lr))
    for(j = 1; j < n; j++)  //fill first row
    {
        matrix[0][j] = matrix[0][j - 1] + o;    //pointer to matrix[0][j][0], thus first element of matrix[0][j][o]
    }

    for(i = 1; i < m; ++i)
    {
        matrix[i] = matrix[i - 1] + n;  //pointer to position of  to matrix[i][0]
        matrix[i][0] = matrix[i - 1][n - 1] + o;    //pointer to  matrix[i][j][0];
        for(j = 1; j < n; ++j)
        {
                    matrix[i][j] = matrix[i][j - 1] + o;
        }
    }
    return matrix;
}

现在,我希望以一种方式移植此代码,使用共享内存IPC和另一个代码以相同的方式访问此矩阵。所以,如果我将内存声明为

ShmID = shmget(ShmKEY, m*n*o*sizeof(lr), IPC_CREAT | 0666);
那么我应该如何将这块内存附加到一个三脚指针,以便内存访问保持不变?

将此作为单个指针附加的示例我可以写

matrix = (lr *) shmat(ShmID, NULL, 0);

此外,我对原始代码中的for循环以及它们实际执行的操作有点挣扎?

编辑:ShmKEY只是一个已知的apriori标识符。

1 个答案:

答案 0 :(得分:2)

关于脚手架的一点说明,数组是单个分配,因此您不能拥有3D数组。它更像是一棵树,旨在模拟3维数组。

例如,您具有根节点:

matrix =  malloc(m * sizeof(lr **));    //allocate first dimension

然后您有一些叶节点:

matrix[0] =  malloc(m * n * sizeof(lr *));

然后您将拥有一个内存块,每个叶节点都指向该内存块:

matrix[0][0] = malloc(m * n * o * sizeof(lr)); // note: you were missing a semicolon here

您实际上只需要最后分配。在谈论一个数组时,一种分配比许多分配要好。这是分配 3维数组的示例,如果可以这样称呼...

typedef lr lr_[o];
typedef lr_ lr__[n];
lr__ *matrix = malloc(m * sizeof matrix[0]);
free(matrix); /* you should probably error check and use your memory first,
               * but we're done with this example now, and when we're done
               * with something `malloc`'d we `free` it.
               */

*注意:如下所述,您可能会丢失typedef并使用更复杂(尽管不是很远)的缩写形式


ShmID = shmget(ShmKEY, m*n*o*sizeof(lr), IPC_CREAT | 0666);
     

那么我应该如何将该内存块附加到三重指针,以使内存访问保持不变?

matrix = (lr *) shmat(ShmID, NULL, 0);

从您的问题来看,这最后一行代码基本上等同于matrix[0][0] = malloc(m * n * o * sizeof(lr)),所以我认为您应该考虑将该行更改为:

matrix[0][0] = shmat(ShmID, NULL, 0);

但是,如果您想像我一样使用单个分配,则可以编写:

ShmID = shmget(ShmKEY, m * n * o * sizeof (lr));
lr__ *matrix = shmat(ShmID, NULL, 0);
shmdt(matrix); // as I understand, `shmdt` is roughly analogous to `free`

然后,您将不需要循环来构造树。 ;)