【问题标题】:Default values in structure结构中的默认值
【发布时间】:2011-08-10 10:07:53
【问题描述】:

如果我对空列表中的队列使用条件 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

【问题讨论】:

  • 我还建议您接受其他问题的一些答案...
  • 考虑删除部分或全部typedefs。使用queue 作为结构标记,Queue 作为struct queue 的别名, QUEUE 作为pointer to struct queue 的别名只是令人困惑。结构的类型定义是常见的做法(但您可以使用相同的标识符:typedef struct queue queue;),但指针类型的类型定义具有潜在危险。显式使用指针语法会迫使您意识到您正在使用指针。例如,我会写void initQueue(struct queue *q);

标签: c queue conditional-statements runtime-error


【解决方案1】:

我想我知道问题出在哪里。在dequeue 中,q->head 将在某个时候变为 NULL。 但是q-&gt;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-&gt;headNULL,但 q-&gt;tail 指向一些无效地址(旧尾部)。

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

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

【讨论】:

  • 我在查看更多代码后立即删除了评论! :)
  • +1 因为这也将成为以后的问题。我认为它不会对 OP 中给出的简单测试造成任何问题(因为队列没有被清空然后被代码重用)。
【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 2014-01-17
    • 1970-01-01
    • 2013-02-24
    • 2016-09-19
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多