Странная ошибка сегментации в массиве указателей C

У меня есть ошибка seg fault в массиве указателей очереди, которая меня ошеломила.

Queue - это простой ADT очереди, реализованный со связанными списками.

G - это "График"

typedef unsigned int u32;

typedef struct NeighbourSt *Neighbour;
struct NeighbourSt {
    u32 index;
    u32 weight;
};

struct VertexSt {
    u32 name;
    u32 degree;
    u32 color;
    u32 order;
    u32 index_neighbours;
};

typedef struct GraphSt {
    u32 vertex_num;
    u32 edge_num;
    u32 delta;
    struct VertexSt *Vertex; 
    struct NeighbourSt *Neighbour;
} GraphSt;

typedef GraphSt *Graph

И очередь:

typedef struct NodeSt *Node;
struct NodeSt {
    void *elem;
    Node next;
    Node prev;
};

typedef struct QueueSt *Queue;
struct QueueSt {
    u32 num_elems;
    Node first;
    Node last;
};

Функции очереди:

    Queue queue_init(void)
    {
        Queue Q = malloc(sizeof(struct QueueSt));
    
        Q -> num_elems = 0;
        Q -> first = NULL;
        Q -> last = NULL;
        return Q;
    }

void enqueue(const Queue Q, void *elem)
{
    Nodo nd = NULL;

    nd = malloc(sizeof(struct NodeSt));

    nd -> elem = elem;
    nd -> next = Q -> first;
    nd -> prev = NULL;
    if (is_empty(Q)) {
        Q -> last = nd;
    } else {
        Q -> first -> prev = nd;
    }

    Q -> first = nd;
    ++Q -> num_elems;
}

void *dequeue(const Queue Q)
{
    Node nd = NULL;
    void *d;

    nd = Q -> first;
    d = nd -> elem;

    Q -> first = Q -> first -> next;

    --Q -> num_elems;
    free(nd);
    nd = NULL;
    return d;
}

И здесь возникает ошибка seg fault (элементы в очереди - 'Vertex'):

u32 vertex_num = G -> vertex_num;
Queue *A = calloc(vertex_num, sizeof(Queue));

for (u32 i = 0; i < vertex_num; i++) {
    A[i] = queue_empty();
}

Neighbour neig = NULL;
for (u32 i = 0; i < vertex_num; i++) {
    degree = G->vertex[i].degree;
    index = G->vertex[i].index_neighbours;
    printf("%p\n", (void*)A[i]);
    for (u32 j = index; j < index + degree; j++) {
        neig = dequeue(A[i]);
        G -> neighbours[j] = *neig;
        free(neig);
        neig = NULL;
    }

    index += degree;
}

Я распечатал значение указателей на очереди, получив следующее:

0x555e1103f840
0x555e1103f860
0x555e1103f880
0x555e1103f8a0
0x555e1103f8c0
0x555e1103f8e0
0x555e1103f900
0x555e1103f920
0x9 (seg fault here)

Код слишком неполный. Что такое A? Что такое Queue? и т.д. Пожалуйста, предоставьте полный код как минимальный воспроизводимый пример.

kaylum 30.03.2021 03:40
0x9 не похож на действительный указатель очереди.
Barmar 30.03.2021 03:41

Откажитесь от привычки создавать typedef для указателей, это только усложняет код. См. stackoverflow.com/questions/750178/…

Barmar 30.03.2021 03:57

В той части, где говорится, что Queue *A = calloc(vertex_num, sizeof(Queue)); - это Queue как typedef для структуры QueueSt?

Matthew Schell 30.03.2021 03:59

Основываясь на его предыдущем typedef, я рискну и угадаю typedef QueueSt *Queue;

Barmar 30.03.2021 04:00

Да, Queue - это указатель на структуру QueueSt

Nibblex 30.03.2021 04:01

Вероятно, у вас есть переполнение буфера или недопустимый указатель где-то в вашей программе, который перезаписывает один из элементов A на 0x9. Используйте такой инструмент, как valgrind, чтобы обнаружить это.

Barmar 30.03.2021 04:03

Кроме того, что такое dequeue? neig = dequeue(A[i]); Я нигде не вижу его заявленного в программе

Matthew Schell 30.03.2021 04:05

dequeue просто получает элемент очереди, а узел, содержащий этот элемент, удаляется.

Nibblex 30.03.2021 04:07

Повторите: укажите полный код как минимальный воспроизводимый пример. Время тратится на повторные запросы на недостающую информацию. То есть код должен быть полным до такой степени, чтобы любой мог его скопировать и запустить точно так, как показано, чтобы воспроизвести проблему.

kaylum 30.03.2021 04:11

относительно: for (u32 i = 0; i < vertex_num; i++) Переменная: vertex_num никогда не инициализируется, поэтому этот оператор генерирует ОШИБКУ

user3629249 30.03.2021 04:50

предполагает, что он инициализирован.

Nibblex 30.03.2021 04:56

рассматривая; typedef struct GraphSt *Graph; Это говорит о том, что Graph является указателем. поэтому этот оператор: Queue *A = calloc(vertex_num, sizeof(Queue)); находится 1) вне какой-либо функции (это ошибка) и 2) объявляет A как указатель на указатель

user3629249 30.03.2021 05:00

Неполный для воспроизведения, но слишком много кода, чтобы мы могли легко вам помочь.

Allan Wind 30.03.2021 08:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
14
38
0

Другие вопросы по теме