[英]linked-list queue, endless loop
I use nested structure to define the linked-list queue: 我使用嵌套结构定义链表队列:
queue.h: 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: 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;
}
but when I use it in the main program, then it jumps into a endless loop, after backtracing, and I knew the problem is at: 但是当我在主程序中使用它时,在回溯之后它跳入一个无限循环,我知道问题出在:
while (q->q_node->next!=NULL) {
count += 1;
q->q_node = q->q_node->next;
}
but it seems correct, but I may make some mistake on my initialization of the two nested struct! 但是这似乎是正确的,但是我在初始化两个嵌套结构时可能会犯一些错误!
PS the I did not list the "free()". PS我没有列出“ free()”。
This loop modifies the list while it traverses it. 该循环在遍历列表时会对其进行修改。 Specifically, it replaces
q->q_node
with q->q_node->next
, which if nothing else will discard your entire loop. 具体来说,它将
q->q_node
替换为q->q_node->next
,如果没有其他选择,则会丢弃整个循环。
while (q->q_node->next!=NULL) {
count += 1;
q->q_node = q->q_node->next;
}
If you want to correctly traverse the list, you need to declare a separate pointer that you use for traversal. 如果要正确遍历该列表,则需要声明用于遍历的单独指针。 Something like this:
像这样:
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;
}
The pointer p
will step along the list without modifying the q_node
pointers along the way. 指针
p
将沿列表移动,而不会一路修改q_node
指针。
You have a similar error in C_enqueue
. 您在
C_enqueue
有类似的错误。 You really want to use a separate pointer to walk the list, and not assign q->q_node
during traversal. 您确实想使用一个单独的指针来遍历列表,而不在遍历期间分配
q->q_node
。 You can fix your C_enqueue
similarly: 您可以类似地修复
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 */
One problem with your code is that your iterations through the queue are destructive: rather than using a temporary variable to iterate your linked list, you perform the iteration using the q_node
itself. 代码的一个问题是,通过队列的迭代具有破坏性:您使用
q_node
本身执行迭代,而不是使用临时变量来迭代链接列表。 This leads to C_get_queue_length
calls effectively destroying the queue, without freeing its nodes (a memory leak). 这导致
C_get_queue_length
调用有效地破坏了队列,而没有释放其节点(内存泄漏)。
Here is an example of how to iterate a list non-destructively, using your "get length" method: 这是一个使用“ 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;
}
Your decision to pre-allocate one node when creating a queue is also questionable: it appears that the head node is unused, and also excluded from the count. 您在创建队列时预分配一个节点的决定也令人怀疑:看来头节点未使用,也被排除在计数之外。 This makes it easier to write the code to insert and delete nodes, but the same could be done with an extra level of indirection (ie a pointer to a pointer).
这使得编写代码来插入和删除节点更加容易,但是同样可以通过额外级别的间接操作(即指向指针的指针)来完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.