在向队列添加元素时在C. Segfault中设计队列

时间:2014-02-22 04:40:36

标签: c pointers segmentation-fault queue

我在用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,这是我创建的所有项目的数据。我不确定问题是什么,答案可能正在盯着我。但我真的很感激这方面的一些帮助。

干杯!

2 个答案:

答案 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()设置nextprev设置为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