【问题标题】:Using mmap to allocate double 2D array使用 mmap 分配双二维数组
【发布时间】:2015-05-10 05:24:23
【问题描述】:

我正在尝试使用 mmap 创建/访问两个不同的 (N+2)*(N+2) 二维双精度数组,以便多个线程可以查看它们自己的部分并更改它,应用更改让所有其他人都能看到。这是我所拥有的:

int main(int argc, char *argv[]) {
    int N = atoi(argv[1]);
    int numProcs = atoi(argv[2]);

    int ARRAY_SIZE = (N+2)*(N+2)*sizeof(double);

    double **grid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
    if (grid == MAP_FAILED) {
        printf("Error mmapping grid\n");
    }
    double **newGrid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
    if (newGrid == MAP_FAILED) {
        printf("Error mmapping grid\n");
    }

当我运行它或尝试访问其中的任何内容时,我遇到了分段错误。我也尝试分配内存:

for(i = 0; i < N+2; i++) {
    for(j = 0; j < N+2; j++) {
        grid[i][j] = malloc(sizeof(double));
    }
}

for(i = 0; i < N+2; i++) {
    for(j = 0; j < N+2; j++) {
        newGrid[i][j] = malloc(sizeof(double));
    }
}

但我遇到了:错误:从不兼容的类型“void *”分配给“double” newGrid[i][j] = malloc(sizeof(double));

我相信我在这里遗漏了 mmap 的工作原理,有人能指出我正确的方向吗?

【问题讨论】:

  • 提示:grid[0] 包含什么?

标签: c arrays double mmap


【解决方案1】:

数组或数组数组是内存中的一个连续区域。使用指向指针的“二维数组”是连续的。

让我们看一些“图像”进行比较:

适当的数组在内存中看起来像这样:

+--------------+--------------+------+------------- ---+--------------+-----+------------------+ |矩阵[0][0] |矩阵[0][1] | ... |矩阵[0][N-1] |矩阵[1][0] | ... |矩阵[M-1][N-1] | +--------------+--------------+------+------------- ---+--------------+-----+------------------+

另一方面,使用指向指针的矩阵看起来像这样:

+-----------+------------+------------+-----+ |矩阵[0] |矩阵[1] |矩阵[2] | ... | +-----------+------------+------------+-----+ | | | | |五 | | +--------------+--------------+------+ | | |矩阵[2][0] |矩阵[2][1] | ... | | | +--------------+--------------+------+ | | |五 | +--------------+--------------+------+ | |矩阵[1][0] |矩阵[1][1] | ... | | +--------------+--------------+------+ | 五 +--------------+--------------+------+ |矩阵[0][0] |矩阵[0][1] | ... | +--------------+--------------+------+

正如您所见,它们的内存布局完全不同,这就是为什么您不能将一个用作另一个。

【讨论】:

  • 我在使用 C 编程的第一个月就学会了这一点,非常困难。
  • 这是有道理的。如果是这样,您对可能的实现有什么想法吗?
【解决方案2】:

如果 N 是编译时常量,或者如果您的编译器支持可变长度数组 (VLA),那么您可以这样做:

double (*grid)[N+2] = (double (*)[N+2]) mmap(NULL, ARRAY_SIZE, ...

grid[4][5] = 2.0;  // setting an element

如果 N 不是常量并且你的编译器不支持 VLA,那么你需要手动偏移:

double *grid = (double *) mmap(NULL, ARRAY_SIZE, ...

grid[4 * (N + 2) + 5] = 2.0;  // setting the same element using manual offsets

【讨论】:

  • 这太棒了!一个很好的解释(以及下面的解释!)如何更好地完成它。我已经实现了这个,现在一切似乎都很完美,所以我谢谢你! :)
  • 数组进入方法时如何指定类型?它最终与 double** 不兼容
  • @alecardv 是的,它的类型肯定不是double **。是double (*)[N+2]double *,具体取决于您遵循的示例。
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2020-09-05
  • 2013-09-18
  • 2012-04-05
  • 1970-01-01
相关资源
最近更新 更多