为什么C中的队列实现会给出分段错误?

时间:2016-09-01 01:45:07

标签: c segmentation-fault queue priority-queue

我在C中实现了一个简单的队列,但是当我在出队后尝试访问Q.front时它给出了分段错误(例如参见int main())。

更确切地说,当我 -

时会出现问题
  1. 将单个元素排队。
  2. 出局。
  3. 将一个或多个元素排队。
  4. 尝试访问Q.front
  5. 然而,当我 -

    时,程序不会出现分段错误或任何错误
    1. 将多个元素排队。
    2. 出征一次。
    3. 排队更多元素(可选)
    4. 成功访问Q.front。
    5. 所以这是我的完整计划 -

      #include <stdio.h>
      #include <stdlib.h> //for malloc
      
      struct qnode
      {
          int r;
          struct qnode *link;
      };
      
      typedef struct qnode qNode;
      
      typedef struct
      {
          qNode *front;
          qNode *rear;
          int qsize;
      }QUEUE;
      
      QUEUE initializeQueue(void)
      {
          QUEUE q;
          q.front = NULL;
          q.rear = NULL;
          q.qsize = 0;
          return q;
      }
      
      
      qNode *createQueueNode(int e)
      {
          qNode *temp;
          temp = (qNode *) malloc(sizeof(qNode));
          if(temp == NULL)
          {
              printf("INSUFFICIENT MEMORY\n");
              exit(0);
          }
          temp->r = e;
          temp->link = NULL;
          return temp;
      }
      QUEUE enqueue(QUEUE q, int e)
      {
          if(q.rear == NULL)
          {
              q.rear = createQueueNode(e);
              q.front = q.rear;
              q.qsize++;
          }
          else
          {
              q.rear->link = createQueueNode(e);
              q.rear = q.rear->link;
              q.qsize++;
          }
          return q;
      }
      
      QUEUE dequeue(QUEUE q)
      {
          qNode *temp;
          if(q.front == NULL)
          {
              printf("queue is empty\n");
              exit(0);
          }
          else
          {
              temp = q.front;
              q.front = q.front->link;
              free(temp);
          }
      
          q.qsize--;
          return q;
      }
      
      
      
      int main(){
      
          QUEUE Q = initializeQueue();
          Q = enqueue(Q, 2);
          printf("%d\n",Q.front->r);
          Q = dequeue(Q);
          Q = enqueue(Q,4);
          printf("%d\n",Q.front->r); // This line is giving segmentation fault 
      
          return 0;
      }
      

2 个答案:

答案 0 :(得分:1)

Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400859 in main () at ./2.c:87
87          printf("%d\n",Q.front->r); // This line is giving segmentation fault 
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6.x86_64
(gdb) p Q
$1 = {front = 0x0, rear = 0x1636010, qsize = 1}

front为null,您可以访问它。 你只需要像gdb这样的debuger来查看你的程序出了什么问题。

答案 1 :(得分:1)

dequeue将q.front设置为NULL(来自q.front-&gt;链接,之前在createQueueNode中设置为NULL)并在q.rear中留下垃圾指针(到free()&#39; d内存) 。由于q.rear不是NULL,所以enqueue中if语句中的第二个块在第二次enqueue调用时执行。哪个写入free()&#39; d内存(q.rear-&gt; link),然后将其解引用到q.rear。我很惊讶它并没有在那里崩溃,实际上,写入了free()&#39; d记忆。如果queue为空,则快速修复可能是将de.ue中的q.rear设置为NULL。您还应该添加一个完整性检查,以便在空队列中运行出队。

此外,你有一种有趣的方式将这种结构像烫手山芋一样传递。为什么不通过引用传递它并在适当的位置修改它而不是返回它?