结构中的默认值

时间:2011-08-10 10:07:54

标签: c queue conditional-statements runtime-error

如果我使用条件q-> head == NULL&&对于空列表中的入队,q-> tail == NULL而不是q-> head == NULL,而两个条件都足够了。谁能告诉我这个错误?我提供以下完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct node Node;
typedef Node* NODE;

struct node{
    int data;
    struct node* next;
};

typedef struct queue Queue;
typedef Queue* QUEUE;
struct queue{
    NODE head;
    NODE tail;
};    

void initQueue(QUEUE q);
void enqueue(QUEUE q,int key);
void dequeue(QUEUE q);
void print(QUEUE q);

int main(int argc, char **argv){
    QUEUE q;
    initQueue(q);
    //print(q);
    dequeue(q);
    enqueue(q,7);

    enqueue(q,9);
    print(q);
    dequeue(q);
    print(q);
    return 0;
}


void initQueue(QUEUE q){
    q=(QUEUE)malloc(sizeof(Queue)*1);
    q->head=NULL;
    q->tail=NULL;
}

void enqueue(QUEUE q,int key){
    NODE temp;
    temp=(NODE)malloc(sizeof(Node)*1);
    temp->data=key;
    temp->next=NULL;

    if(q->head==NULL && q->tail==NULL){
        q->head=temp;
        q->tail=temp;
    }
    else{
        q->tail->next=temp;
        q->tail=temp;
    }

}//end of enqueue()

void dequeue(QUEUE q){
    NODE temp;
    if(q->head==NULL){
        printf("queue is empty");
    }
    else{
        temp=q->head;
        q->head=temp->next;
        free(temp);    
    }
}

void print(QUEUE q){
    NODE cur;
    if(q->head==NULL){
        printf("Queue is empty!\n");
    }
    else{
        cur=q->head;

        while(cur!=NULL){
            printf("%d",cur->data);
            cur=cur->next;

        }//end of while    
    }//end of else    
}//end of print

2 个答案:

答案 0 :(得分:2)

我想我知道问题所在。在dequeue中,q-> head将在某些时候变为NULL。 q->tail仍然指向一些虚假地址

void dequeue(QUEUE q){
    NODE temp;
    if(q->head==NULL){
        printf("queue is empty");
    }
    else{
        temp=q->head;
        q->head=temp->next;
        free(temp);    
    }
}

然后,在您的队列中,q->headNULLq->tail指向某个无效地址(旧尾)。

if(q->head==NULL && q->tail==NULL)

所以它不会输入if而是会尝试q->tail->next=temp; 未定义,因为t->tail已被释放。

答案 1 :(得分:2)

您应该始终编译并启用所有警告:

$ gcc -Wall -Wextra -W -pedantic -std=c99 q.c
q.c: In function ‘main’:
q.c:25:14: warning: unused parameter ‘argc’
q.c:25:27: warning: unused parameter ‘argv’
q.c:27:14: warning: ‘q’ is used uninitialized in this function

你可以忽略的前两个警告(现在),但第三个暗示你的问题。

int main(int argc, char **argv){
    QUEUE q;
    initQueue(q);

[snip]

void initQueue(QUEUE q){
    q=(QUEUE)malloc(sizeof(Queue)*1);

initQueue中,您正在修改本地QUEUE(指针)q而不是main中的{。}}。

更改initQueue的签名以获取QUEUE*并在该功能中使用*q或执行以下操作:

int main(int argc, char **argv){
    QUEUE q;
    q = initQueue();

[snip]

QUEUE initQueue(){
    QUEUE q=(QUEUE)malloc(sizeof(Queue)*1);
    q->head = q->tail = NULL;
    return q;
}