У меня есть ошибка 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)
0x9
не похож на действительный указатель очереди.
Откажитесь от привычки создавать typedef для указателей, это только усложняет код. См. stackoverflow.com/questions/750178/…
В той части, где говорится, что Queue *A = calloc(vertex_num, sizeof(Queue));
- это Queue
как typedef для структуры QueueSt
?
Основываясь на его предыдущем typedef, я рискну и угадаю typedef QueueSt *Queue;
Да, Queue - это указатель на структуру QueueSt
Вероятно, у вас есть переполнение буфера или недопустимый указатель где-то в вашей программе, который перезаписывает один из элементов A
на 0x9
. Используйте такой инструмент, как valgrind
, чтобы обнаружить это.
Кроме того, что такое dequeue
? neig = dequeue(A[i]);
Я нигде не вижу его заявленного в программе
dequeue просто получает элемент очереди, а узел, содержащий этот элемент, удаляется.
Повторите: укажите полный код как минимальный воспроизводимый пример. Время тратится на повторные запросы на недостающую информацию. То есть код должен быть полным до такой степени, чтобы любой мог его скопировать и запустить точно так, как показано, чтобы воспроизвести проблему.
относительно: for (u32 i = 0; i < vertex_num; i++)
Переменная: vertex_num
никогда не инициализируется, поэтому этот оператор генерирует ОШИБКУ
предполагает, что он инициализирован.
рассматривая; typedef struct GraphSt *Graph;
Это говорит о том, что Graph
является указателем. поэтому этот оператор: Queue *A = calloc(vertex_num, sizeof(Queue));
находится 1) вне какой-либо функции (это ошибка) и 2) объявляет A
как указатель на указатель
Неполный для воспроизведения, но слишком много кода, чтобы мы могли легко вам помочь.
Код слишком неполный. Что такое
A
? Что такоеQueue
? и т.д. Пожалуйста, предоставьте полный код как минимальный воспроизводимый пример.