我在用C编写的队列程序有问题。这是一个循环队列,所以最后一项也必须指向第一项。 addQueue函数中存在问题。首先,我检查头指针是否设置为NULL,如果是,则将第一个项添加到队列中。但是,head不等于NULL,然后我将项添加到队列的末尾。我创建一个迭代指针迭代,直到它找到结束时: iterate-> next == * head; 我遇到的问题是,当我创建迭代并将其设置为* head时,它不会按预期运行。这是我的代码和我收到的输出,我在代码中添加了一些打印来显示我遇到的问题。
#include <stdlib.h>
#include <stdio.h>
//define the Q element struct
typedef struct _item{
struct _item* next;
struct _item* prev;
int data;
} item;
item * newItem(){
item * node = malloc(sizeof(item));
return node;
}
void initQueue(item ** head){
*head = NULL; //Empty queue means head points to NULL
}
void addQueue(item ** head, item item_p){
//create new item
item * newIt = newItem();
newIt = &item_p;
printf("NewItem: %d\n\n", newIt->data);
//if *head is NULL, make it point to item
if(*head == NULL)
{
*head = newIt; //set head to address of item
newIt->next = *head;
printf("Again: %p\n\n", *head);
}
//else the list is not empty, add item to end of list
else
{
item * iterate = NULL;
iterate = *head;
printf("it: %p head: %p\n\n", iterate, *head);
/*while (iterate->next != *head)
{
iterate = iterate->next;
}
iterate->next = newIt;
newIt->next = *head;*/
}
}
这是我编写的用于测试函数的.c文件:
#include "q.h"
#include <stdio.h>
int main ()
{
item i1;
i1.data = 1;
item i2;
i2.data = 2;
item i3;
i3.data = 3;
item * headTemp;
initQueue(&headTemp);
addQueue(&headTemp, i1);
printf("HEAD: %d\n", headTemp->data);
addQueue(&headTemp, i2);
printf("HEAD: %d\n", headTemp->data);
addQueue(&headTemp, i3);
return 0;
}
输出是:
NewItem: 1
Again: 0x7fff2252eb10
HEAD: 1
NewItem: 2
it: 0x7fff2252eb10 head: 0x7fff2252eb10
HEAD: 2
NewItem: 3
it: 0x7fff2252eb10 head: 0x7fff2252eb10
Segmentation fault
我创建了三个要插入队列的项目。第一个是没有问题的。但是,当我插入第二个项目时,我遇到了问题。无论我放入队列的是什么,headTemp-&gt;数据应该保持不变,但是从1到2到3,这是我创建的所有项目的数据。我不确定问题是什么,答案可能正在盯着我。但我真的很感激这方面的一些帮助。
干杯!
答案 0 :(得分:0)
您的addQueue()
功能不合适。
void addQueue(item ** head, item item_p){
28 //create new item
29 item * newIt = newItem();
30 newIt = &item_p;
31 printf("NewItem: %d\n\n", newIt->data);
32
33 //if *head is NULL, make it point to item
34 if(*head == NULL)
35 {
36 *head = newIt; //set head to address of item
37 newIt->next = *head;
38 printf("Again: %p\n\n", *head);
39 }
在此,您执行newItem()
以获取新分配的节点,但是您再次将其重新分配给第30行的&itemp_p
。这不好,因为您没有使用已分配的内存,但项目i1, i2, i3
中声明的变量main()
。
此外,在newItem()
设置next
和prev
设置为NULL
17 item * newItem(){
18
19 item * node = malloc(sizeof(item));
if(node) { //You can use calloc too.
node->next = NULL;
node->prev = NULL;
}
20 return node;
21 }
答案 1 :(得分:0)
感谢您发布可粘贴的代码。出门,这是错误的:
item * newIt = newItem();
newIt = &item_p;
这是一个直接的内存泄漏。更糟糕的是,替换它的地址是一个按值自动变量。因此,只要此函数完成,该地址即使评估也将无效,更不用说取消引用了。
接下来,您需要使用所有成员变量的有效状态填充节点。如何执行此操作取决于您,但最简单的方法是在节点创建代码中。要真正做到这一点,您的节点创建代码应该是“工厂”功能。即它应该作为初始化节点所需的参数。所以先做这个:
item* newItem( int data )
{
item * node = malloc(sizeof(item));
if (item == NULL)
{
perror("failed to allocate node.");
exit(EXIT_FAILURE);
}
node->data = data;
node->next = node->prev = NULL;
return node;
}
一旦掌握了这一点,您就可以修改addQueue
来执行此操作:
void addQueue(item** head, int data)
{
item *prev = NULL;
while (*head)
{
prev = *head;
head = &prev->next;
}
*head = newItem(data);
(*head)->prev = prev;
}
这段代码仍然不是一个双端队列。你需要两个指针才能做到这一点,保留它们的最佳位置是在一个单独的结构中,还有一个计数来进行大小查询O(1)。正确完成后,插入是完整双端的O(1),但最终会到达那里。
无论如何,下面会出现一个更新后的主程序,用于测试所有内容。最后你需要一个pop-functoin等。
int main()
{
item *q = NULL;
for (int i=1; i<=20; ++i)
addQueue(&q, i);
item *p = q;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return 0;
}
<强>输出强>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20