用指向 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'
}
我有一个二维指针数组:
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'
}