2016-09-01 4 views
1

Я выполнил простую очередь в C, но при этом выдал ошибку сегментации при попытке получить доступ к Q.front после удаления (см., Например, int main()).Почему эта реализация очереди в C дает ошибку сегментации?

Чтобы быть более точным, то проблема возникает, когда я -

  1. Епдиеие один элемент.
  2. Dequeue его.
  3. Включить один или несколько элементов.
  4. Попробуйте получить доступ Q.front

Однако программа не дает ошибку сегментации или какую-либо ошибку, когда я -

  1. Enqueue более чем один элемент.
  2. Dequeue один раз.
  3. Задать больше элементов (необязательно)
  4. Доступ к Q.front успешно.

Так что это моя полная программа -

#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; 
} 

ответ

1

dequeue устанавливает q.front в NULL (из ссылки q.front->, которая ранее была установлена ​​в NULL в createQueueNode) и оставляет указатель на мусор (в свободную() 'd-память) в q.rear. Поскольку q.rear не является NULL, второй блок в операторе if в очереди выполняется во втором вызове для очереди. Что пишет в free() 'd memory (q.rear-> link), а затем разыгрывает в q.rear. Я удивлен, что он не рухнет прямо там, на самом деле, с записью в свободную() память. Быстрое исправление, вероятно, было бы установить q.rear в NULL в dequeue, если очередь пуста. Вы также должны добавить проверку на работоспособность, так что деактивация не будет выполняться в пустой очереди.

Кроме того, у вас есть интересный способ передать эту структуру вокруг, как горячий картофель. Почему бы не передать его по ссылке и изменить его вместо того, чтобы возвращать его?

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} 

фронт утратившим вы к нему доступ. вам просто нужен debuger, например gdb, чтобы узнать, что не так с вашей программой.

+0

Но как это null, если я выделил еще один элемент после операции dequeue? –

+0

Должен ли Q.front указать на этот новый элемент в очереди? –

 Смежные вопросы

  • Нет связанных вопросов^_^