如何确保二维数组在内存中连续分配

How to ensure a 2D array is allocated contigously in memory

我正在通过 MPI 发送二维数组,为了使其正常工作,需要在内存中连续分配数组。

我是这样分配的:

int **array;
array = malloc(size1 * sizeof( *(array) );
for (int k = 0; k < size1; k++)
    array[k] = malloc(size2 * sizeof(**(array));

那我想用:

MPI_Send(array, size1*size2, MPI_INT, target_pe, tag, MPI_COMM_WORLD);

如何确保数组是连续分配的?

目前我正在尝试这个:

for (int k = 0; k < size1; k++)
    MPI_Send(array[k], size2, MPI_INT, target_pe, tag, MPI_COMM_WORLD);

这会导致稍后在程序的不相关部分出现段错误。但是,如果我将元素 1 个发送 1 个,它就可以工作。

使用:

int (*array)[size2] = malloc(size1 * sizeof *array);
if (!array) Handle error…

如果 size2 不是常量并且您的 C 实现不支持可变长度数组,则使用:

int *array = malloc(size1 * size2 * sizeof *array);
if (!array) Handle error…

在这种情况下,您将不得不使用手动地址算法来访问数组元素。使用 array[i*size2 + j].

而不是 array[i][j]

您无法通过使用对 malloc() 的顺序调用来确保这一点。你可以做的是,你可以在内存中从 malloc(size1 * size2) space 开始分配,然后你可以根据需要拆分你分配的缓冲区。你现在可以说 array[i] 在内存中实际上是 array[i * size2]

正确的方法是在单次操作中为二维数组分配内存。然后由于数组在 C 中并不是真正的第一 class 公民,更不用说多维数组,您将必须为指针数组分配内存并使其元素指向每一行的开头:

int *mem = malloc(sizeof(*mem) * size1 * size2);
int **array = malloc(size1 * sizeof(*array));
for (int k = 0; k < size1; k++) {
    array[k] = mem + k * size2 * sizeof(*mem);
}

这将确保在需要将数组传递给例程时进行连续分配,并且仍然允许以 array[i][j];

访问元素

How to ensure a 2D array is allocated contiguously in memory

一步分配。

示例使用支持可变长度数组的 C99 代码。这里使用了指向 VLA 的指针。

// ptr is a pointer to a 2D array
int (*ptr)[size1][size2] = malloc(sizeof *ptr); 
(*ptr)[0][0] = 1;            // One corner of the 2D array
(*ptr)[size-1][size-1] = 2;  // Opposite corner of the 2D array

稍后我会查看示例 MPI() 代码。