我使用嵌套结构来定义链表列表:
queue.h:
#define QUEUE_MAX_SIZE 4096
struct QUEUE_NODE {
char *string;
struct QUEUE_NODE *next;
}queue_node;
struct COMMON_QUEUE {
struct QUEUE_NODE *q_node;
}common_queue;
=================================
queue.c:
/* here I define the operations */
struct COMMON_QUEUE *C_init_queue() {
struct QUEUE_NODE *head;
head = malloc(sizeof(struct QUEUE_NODE));
if (head==NULL) {
fprintf(stderr, "Insufficient memory!!!");
return NULL;
}
struct COMMON_QUEUE *new_queue;
new_queue = malloc(sizeof(struct COMMON_QUEUE));
if (new_queue==NULL) {
fprintf(stderr, "Insufficient memory!!!");
return NULL;
}
head->next = NULL;
head->string = NULL;
new_queue->q_node = head;
return new_queue;
}
int C_get_queue_length(struct COMMON_QUEUE *q) {
int count;
count = 0;
while (q->q_node->next!=NULL) {
count += 1;
q->q_node = q->q_node->next;
}
return count;
}
int C_enqueue(struct COMMON_QUEUE *q, char *in) {
if (C_get_queue_length(q)>=QUEUE_MAX_SIZE) {
fprintf(stderr, "Linked queue is full!!!");
return ERROR;
}
struct QUEUE_NODE *new_node;
new_node = malloc(sizeof(struct QUEUE_NODE));
if (new_node==NULL) {
return ERROR;
}
new_node->next = NULL;
new_node->string = NULL;
while (q->q_node->next!=NULL) {
q->q_node = q->q_node->next;
}
new_node->next = q->q_node->next;
q->q_node->next = q->q_node;
new_node->string = in;
return OK;
}
但是当我在主程序中使用它时,它会在回溯后跳转到无限循环,我知道问题出在:
while (q->q_node->next!=NULL) {
count += 1;
q->q_node = q->q_node->next;
}
但似乎是正确的,但我可能会在初始化两个嵌套结构时犯一些错误!
P.S。我没有列出“免费()”。
答案 0 :(得分:2)
此循环在遍历列表时修改列表。具体来说,它会将q->q_node
替换为q->q_node->next
,如果没有其他内容会丢弃您的整个循环。
while (q->q_node->next!=NULL) {
count += 1;
q->q_node = q->q_node->next;
}
如果要正确遍历列表,则需要声明用于遍历的单独指针。像这样:
int C_get_queue_length(struct COMMON_QUEUE *q) {
int count;
struct COMMON_QUEUE *p = q->q_node;
count = 0;
while (p->next != NULL) {
count += 1;
p = p->next;
}
return count;
}
指针p
将沿着列表步进,而不会修改沿途的q_node
指针。
C_enqueue
中有类似的错误。您确实希望使用单独的指针来遍历列表,而不是在遍历期间分配q->q_node
。您可以同样修复C_enqueue
:
p = q->q_node;
while (p->next != NULL) {
p = p->next;
}
p->next = new_node; /* append the new node after where the list traversal stopped */
new_node->next = NULL; /* always NULL, because you always insert at the end */
答案 1 :(得分:1)
您的代码的一个问题是您在队列中的迭代是破坏性的:而不是使用临时变量来迭代链表,您可以使用q_node
本身执行迭代。这导致C_get_queue_length
调用有效地破坏队列,而不释放其节点(内存泄漏)。
以下是如何使用“获取长度”方法非破坏性地迭代列表的示例:
int C_get_queue_length(struct COMMON_QUEUE *q) {
int count;
count = 0;
struct QUEUE_NODE node = q->q_node;
while (node->next != NULL) {
count++;
node = node->next;
}
return count;
}
您在创建队列时预先分配一个节点的决定也值得怀疑:看起来头节点未使用,并且也从计数中排除。这使得编写插入和删除节点的代码变得更容易,但是可以通过额外的间接级别(即指向指针的指针)来完成相同的操作。