在C.Segfault中将元素添加到队列时设计队列
我用C编写的队列程序有问题。这是一个循环队列,因此最后一项也必须指向第一项。addQueue函数中存在此问题。首先检查head指针是否设置为NULL,如果设置为NULL,则将第一项添加到队列中。但是,head不等于NULL,然后我将该项添加到队列的末尾。我创建了一个迭代指针来迭代,直到在以下情况下找到结束: 迭代->下一步==*头部; 我遇到的问题是,当我创建iterate并将其设置为*head时,它并没有正常运行。这是我的代码和我收到的输出,我在代码中添加了一些打印,以显示我遇到的问题在C.Segfault中将元素添加到队列时设计队列,c,pointers,segmentation-fault,queue,C,Pointers,Segmentation Fault,Queue,我用C编写的队列程序有问题。这是一个循环队列,因此最后一项也必须指向第一项。addQueue函数中存在此问题。首先检查head指针是否设置为NULL,如果设置为NULL,则将第一项添加到队列中。但是,head不等于NULL,然后我将该项添加到队列的末尾。我创建了一个迭代指针来迭代,直到在以下情况下找到结束: 迭代->下一步==*头部; 我遇到的问题是,当我创建iterate并将其设置为*head时,它并没有正常运行。这是我的代码和我收到的输出,我在代码中添加了一些打印,以显示我遇到的问题 #i
#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;*/
}
}
我创建了三个要插入队列的项。第一个是放置在没有问题。但是,当我插入第二项时,我遇到了问题。headTemp->数据应该保持不变,无论我将什么放入队列,但是它从1到2到3,这是我创建的所有项目的数据。我不确定问题出在哪里,答案可能就在我面前。但我真的很感激你能帮我
干杯 您的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
。这不好,因为您没有使用分配的内存,而是使用main()
中声明的项变量i1、i2、i3
另外,在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 }
感谢您发布可粘贴代码。走出大门,这是错误的:
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;
}
这段代码离deque还有很长的路要走。要做到这一点,您需要两个指针,保存它们的最佳位置是在一个单独的结构中,以及进行大小查询的计数O(1)。正确地做,插入是O(1)在一个完整的deque中,但您最终会到达那里
无论如何,下面会出现一个更新的main,用于测试它所做的一切。最终你会想要一个流行的function,等等
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;
}
不要将结构作为参数传递。使用指针。请不要给你的行编号。剪切用于测试的粘贴代码是毫无价值的。如果您必须提醒注意某一行的特定错误,请添加一条注释,说明“这是行”。也就是说,这对学术界来说是一个悲哀的见证,当我真的很想在海报上投一个问题的时候,仅仅是因为海报的代表人数不足1K,并且没有正确地投下
malloc()
(干得好,顺便说一句)。查看您的代码,看看您是否可以找到新节点在哪里有next
和prev
指针,如果没有设置为以前的有效地址,指针将初始化为NULL。另外,在前两行中,您会立即泄漏addQueue
方法中的内存。这不是java。您的代码将自动变量推送到队列中,一旦函数返回,该变量将无效。您没有将元素添加到列表末尾。@WhozCraig感谢您提供有关行号的提示。这是我第一篇关于stackoverflow的帖子,所以我还在努力适应。非常感谢。这帮了大忙。
void addQueue(item** head, int data)
{
item *prev = NULL;
while (*head)
{
prev = *head;
head = &prev->next;
}
*head = newItem(data);
(*head)->prev = prev;
}
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