Segfault при назначении структуры в 2d массиве через вызов функции - PullRequest
1 голос
/ 20 февраля 2020

У меня есть следующее 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_count и neighbours должны быть установлены позже)

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

    return cell;
}

У меня есть myfun для инициализации переменных neighbours и neighbour_count для матрицы cell_t, которую он читает из какого-то внешнего источника.

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 Я инициализирую пустую матрицу указателей на объекты ячеек, а затем l oop по ширине и высоте, создавая ячейки и сохраняя указатели на них в матрице. Затем в myfun я просто получаю доступ к переменной соседних клеток этих ячеек и устанавливаю ее. Но, видимо, я ошибаюсь, так как это происходит с ошибками (не всегда на первом l oop, хотя, как правило, довольно быстро).

Я думаю, возможно, я сделал что-то не так, что матрица cells на самом деле не содержит указателей на cell_t структур. Но я не вижу, что я делаю неправильно.

Я получаю предупреждение о том, что «передаю аргумент 1« myfun »из несовместимого типа указателя», и вместо этого он должен иметь тип cell_t * (*)[(sizetype)(height)] ; возможно, это помогает? Я ожидаю, что проблем не будет, так как struct_t *** должно быть хорошо для двумерного массива указателей, не так ли?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

Тип первого параметра функции

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] ){

, которая объявляет ту же функцию.

0 голосов
/ 20 февраля 2020

В вашем коде неправильно определено определение указателя.

cell_t *cells[width][height];

Это определение не для указателя, который указывает на массив 2D. Как и @Lundin, прокомментированный выше, он не совместим с cell_t ***cells. Если вы хотите определить указатель, который указывает на массив 2D, вы можете использовать следующий код:

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

Указатель ptr совместим с ***cells в вашем коде

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...