【问题标题】:3 Dimensional array memory allocation3 维数组内存分配
【发布时间】:2018-04-06 08:52:22
【问题描述】:

我有一个为 3D 数组分配内存的代码,称为“矩阵”,我通常将 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 只是一个已知的标识符。

【问题讨论】:

  • @Someprogrammerdude 我的错,这是一个错字。实际上它应该是 mno*sizeof(lr)。但问题仍然存在。 (这是一个错字,现已更正)
  • 您需要使用实际的 3D 数组。见Correctly allocating multi-dimensional arrays
  • 我会说matrix[0][0] = shmat(ShmID, NULL, 0); 和其他一切都保持不变。
  • @user3386109 我确实明白了你的意思,但是必须为矩阵(如***)、矩阵[0](如**)赋值,然后它们必须交织在一起可以再次以matrix[i][j][k] 的身份访问矩阵(这是参考需要访问矩阵的其他代码。对于此代码,我确实明白您的观点,即仅更改行将保持其他内容不变。)
  • matrixmatrix[0] 的分配不需要在共享内存中。只有double 值本身需要在共享内存中。 OTOH Lundin 是正确的,您可以声明一个指针 lr (*matrix)[n][o] = shmat(ShmID, NULL, 0); 并改用它,假设编译器支持 VLA。

标签: c arrays memory multidimensional-array ipc


【解决方案1】:

稍微有点迂腐,数组是一个单一的分配,所以你所拥有的不能是一个 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.
               */

*注意:正如下面所指出的,您可以省略typedefs 并使用更复杂(虽然不是很远)、更简洁的符号


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`

那么你就不需要循环来构建你的树了。 ;)

【讨论】:

  • 一旦你得到它,我发现lr (*matrix)[m][n] = malloc(...) 比这种类型定义更具可读性。
  • 言归正传。我对矩阵三元组指针使用文件范围外的声明和定义,因为这些大矩阵在整个代码中用作全局变量。如果我使用您分配矩阵的方式,那么矩阵的范围外文件声明应该是什么。
  • 应该extern lr__ *matrixlr__ *matrix 工作吗?
  • @datapanda 当然,只要两个模块都意识到它们在谈论相同的类型...您可能还想考虑一些共享维度的方法。
  • @datapanda 更重要的是,mno 可能应该是硬编码的,或者也应该有一些 external 曝光。
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多