通过函数调用分配给二维数组中的结构时出现段错误

Segfault when assigning to struct within 2d array through function call

我有以下 typedef:

typedef struct cell_t {
    int x; // x coord of this cell                                                                                 
    int y; // y coord of this cell                                                                                 
    int neighbour_count; // Size of the following array                                                            
    struct cell_t **neighbours; // array of pointers to neighbours                                                 
} cell_t;

和一些初始化该类型的代码(neighbour_countneighbours稍后设置)

cell_t *create_cell(int x, int y){
    cell_t *cell = malloc(sizeof(cell_t));
    cell->x = x;
    cell->y = y;

    return cell;
}

我有 myfun 来为 cell_t 的矩阵初始化 neighboursneighbour_count 变量,它从一些外部源读取。

int myfun(cell_t ***cells, int width, int height){
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            // Read data from source, including the long `list_size`

            cells[x][y]->neighbour_count = (int) list_size; // This segfaults
        }
    }
}

所以在我的 main 中,我有以下内容:

int width = 3, height = 3;

cell_t *cells[width][height];

for (int x = 0; x < width; x++){
    for(int y = 0; y < height; y++){
        cells[x][y] = create_cell(x,y);
    }
}

myfun(cells, width, height);

设置邻居计数时,它会出现段错误(如代码的第三块中所标记)。

我想我正在做的是,在我的 main 中,我初始化了一个指向单元格对象的空指针矩阵,然后遍历宽度和高度,创建单元格,并将指向它们的指针存储在矩阵。然后在 myfun 中,我只是访问这些单元格的变量 neighbour_count 并进行设置。但显然我错了,因为它会出现段错误(虽然并不总是在第一个循环中,但通常很快)。

我在想,也许我做错了什么,矩阵 cells 实际上并不包含指向 cell_t 结构的指针。但是我看不出我做错了什么。

我收到 "passing argument 1 of ‘myfun’ from incompatible pointer type" 的警告,它应该是 cell_t * (*)[(sizetype)(height)] 类型;也许这有帮助?我希望不会有问题,因为 struct_t *** 应该适用于二维指针数组,不是吗?

第一个函数参数的类型

int myfun(cell_t ***cells, int width, int height){

和提供的参数类型

myfun(cells, width, height);

互不对应。函数参数声明为

cell_t *cells[width][height];

隐式转换为指向其第一个元素的指针。也就是说它的类型是 cell_t * ( * )[height].

因此相应的函数应该这样声明

int myfun( int width, int height, cell_t * cells[][height] ){

或喜欢

int myfun( int width, int height, cell_t * ( *cells )[height] ){

声明相同的函数。

你的代码中有一件事是不正确的,我知道是指针的定义。

cell_t *cells[width][height];

此定义不适用于指向二维数组的指针。就像@Lundin 上面评论的那样,它与 cell_t ***cells 不兼容。如果你想定义一个指向二维数组的指针,你可以使用下面的代码:

cell_t cells[width][height];
cell_t *ptr = &cells;

指针 ptr 与代码中的 ***cells 兼容