用指向 C 中结构的指针填充二维指针数组

Fill a 2d array of pointers with pointers to structs in C

我有一个二维指针数组:

typedef struct Cell{
   Position p;
   unsigned int value;
} Cell;

typedef struct Position{
    unsigned int x;
    unsigned int y;
} Position;

int size = 4;
Cell ***cells = malloc(sizeof(Cell**) * size);
int i,j;
for(i = 0; i < size; i++){
    cells[i] = malloc(sizeof(Cell*) * size);
    for(j = 0; j < size; j++){
        cells[i][j] = malloc(sizeof(Cell));
    }
}

我现在要做的是用指向单元格的指针填充这个数组,并初始化这些单元格以包含值 0,如下所示:

for(i = 0; i < size; i++){
    for(j = 0; j < size; j++){
        Position p = {i,j};
        Cell c = {p, 0};
        cells[i][j] = &c; //This doesn't work
    }
}

如您所知,将 c 的地址写入指针 cells[i][j] 并不理想,因为现在每个指针都指向相同的地址。但是我不知道如何用指向各个地址的指针填充这个数组。

我试过这样的事情:

cells[i][j]->value = 0;

这当然也行不通。谁能告诉我如何解决我的问题?

我不确定你为什么说 cells[i][j]->value = 0; 不起作用,我相信它应该。

这应该可以设置所有成员。

Cell ***cells = malloc(sizeof(Cell**) * size);
for(i = 0; i < size; i++){
    cells[i] = malloc(sizeof(Cell*) * size);
    for(j = 0; j < size; j++){
        cells[i][j] = malloc(sizeof(Cell));
        cells[i][j]->p.x = i;
        cells[i][j]->p.y = j;
        cells[i][j]->value = 0;
    }
}

您已经得到了答案,但我认为没有明显的理由进行那么多分配,除非 sizeof(Cell) * size * size 大到足以使单个分配失败(但分配较小的部分不会)。我建议只进行一次分配,这会带来一些好处。排名不分先后:

  • 大多数情况下分配速度更快。
  • 更快地访问将被紧密打包的元素,因此对缓存更友好。
  • 内存管理更简单 - 只需检查一个指针,free
  • 分配的总内存比为大量指针分配内存时少。

示例 1 - 使 cells 成为指向 Cell[size].

size 个元素中第一个元素的指针
// one allocation:
Cell (*cells)[size] = malloc( size * sizeof *cells );

if(cells == NULL) exit(1); // check for allocation failure

for(int i = 0; i < size; i++){
    for(int j = 0; j < size; j++){
        cells[i][j].p.y = i;
        cells[i][j].p.x = j;
        cells[i][j].value = 0;
    }
}

示例 2 - 使 cells 成为指向单个 Cell[size][size]:

的指针
// one allocation:
Cell (*cells)[size][size] = malloc( sizeof *cells );

if(cells == NULL) exit(1); // check for allocation failure

for(int i = 0; i < size; i++){
    for(int j = 0; j < size; j++){
        (*cells)[i][j].p.y = i;
        (*cells)[i][j].p.x = j;
        (*cells)[i][j].value = 0;
    }
}

其他:

for(i = 0; i < size; i++){
    for(j = 0; j < size; j++){
        Position p = {i,j};
        Cell c = {p, 0};
        cells[i][j] = &c; //This doesn't work
    }
    // to this line, 'c' & 'p' will be freed since it was allocated on stack not heap.
    // 'c' & 'p' will be freed when program gets out of 2nd for loop, so either you can
    // use memcpy to copy 'c' into cells[i][j] or use malloc to allocate 'c' and 'p'
}