[英]linked-list queue, endless loop
我使用嵌套结构定义链表队列:
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;
}
但是这似乎是正确的,但是我在初始化两个嵌套结构时可能会犯一些错误!
PS我没有列出“ free()”。
该循环在遍历列表时会对其进行修改。 具体来说,它将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 */
代码的一个问题是,通过队列的迭代具有破坏性:您使用q_node
本身执行迭代,而不是使用临时变量来迭代链接列表。 这导致C_get_queue_length
调用有效地破坏了队列,而没有释放其节点(内存泄漏)。
这是一个使用“ get 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;
}
您在创建队列时预分配一个节点的决定也令人怀疑:看来头节点未使用,也被排除在计数之外。 这使得编写代码来插入和删除节点更加容易,但是同样可以通过额外级别的间接操作(即指向指针的指针)来完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.