分段错误:在 C 中实现优先级队列

Posted

技术标签:

【中文标题】分段错误:在 C 中实现优先级队列【英文标题】:Segmentation fault: Implementing Priority Queues in C 【发布时间】:2021-05-04 17:18:36 【问题描述】:

我正在尝试实现优先级。较高的变量先验值意味着我的代码中的优先级较低。这里是:

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

struct MinMax_PriorityQueue
    int ele, prior;
    struct MinMax_PriorityQueue *next;
;

int isEmpty(struct MinMax_PriorityQueue **pq)
    return ((*pq)==NULL);


int checkPriority(int p)
    return(p>0);


void enqueue(struct MinMax_PriorityQueue **pq, int x, int p)
    struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
    //struct MinMax_PriorityQueue *temp1=*pq;
    if(!checkPriority(p))
        printf("Priority should be greater than 0");
        return;
    
    temp->ele=x;
    temp->prior=p;
    temp->next=NULL;
    /*if(isEmpty(pq))
        *pq=temp;
    
    while(temp1->next!=NULL)
        temp1=temp1->next;
    */
    (*pq)->next=temp;
    printf("The item %d with priority %d has been enqueued into the priority queue\n", x, p);


int maxPriority(struct MinMax_PriorityQueue **pq)
    struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
    temp=*pq;
    int maxp=temp->prior;
    while(temp!=NULL)
        if(temp->prior<=maxp)
            maxp=temp->prior;
        temp=temp->next;
    
    return maxp;


void dequeue(struct MinMax_PriorityQueue **pq)
    if(isEmpty(pq))
        printf("The priority queue is empty. No more elements can be removed!\n");
    
    int maxp=maxPriority(pq);
    struct MinMax_PriorityQueue *temp=*pq;
    while(temp!=NULL)
        if(temp->prior==maxp)
            printf("The item %d with priority %d has been dequeued from the priority queue\n", temp->ele, temp->prior);
            free(temp);
            break;
        
        temp=temp->next;
    


void minSearch(struct MinMax_PriorityQueue **pq)
    struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
    temp=*pq;
    int minp=0;
    while(temp!=NULL)
        if(temp->prior>=minp)
            minp=temp->prior;
        temp=temp->next;
    
    temp=*pq;
    while(temp!=NULL)
        if(temp->prior==minp)
            printf("The element %d has minimum priority\n", temp->ele);
        
        temp=temp->next;
    


void maxSearch(struct MinMax_PriorityQueue **pq)
    int maxp=maxPriority(pq);
    struct MinMax_PriorityQueue *temp=*pq;
    while(temp!=NULL)
        if(temp->prior==maxp)
            printf("The element %d has maximum priority\n", temp->ele);
        
        temp=temp->next;
    


void display(struct MinMax_PriorityQueue *pq)
    struct MinMax_PriorityQueue *temp=pq;
    printf("The contents of the priority queue are:\n");
    if(isEmpty(&temp))
        printf("Nothing to be shown, the priority queue is empty.\n");
        return;
    
    for(int i=0;temp!=NULL;temp=temp->next)
        if(i)
            printf(" ------ \n");
        
        printf("|  %d  |\n", temp->ele);
        i=1;
    


int main()

    int choice, element, priority;
    printf("LET'S START WITH AN EMPTY QUEUE\n\n");
    struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
    pq=NULL;
    while(1)
        printf("\nMENU\n");
        printf("----\n");
        printf("\t1. Enqueue\n");
        printf("\t2. Dequeue\n");
        printf("\t3. Display queue\n");
        printf("\t4. Search minimum priority\n");
        printf("\t5. Search maximum priority\n");
        printf("\t6. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch(choice)
            case 1: printf("Enter the element to be enqueued: ");
                    scanf("%d", &element);
                    printf("Enter its priority: ");
                    scanf("%d", &priority);
                    enqueue(&pq, element, priority);
                    break;
            case 2: dequeue(&pq);
                    break;
            case 3: display(pq);
                    break;
            case 4: minSearch(&pq);
                    break;
            case 5: maxSearch(&pq);
                    break;
            case 6: printf("Program terminated successfully!\n");
                    return 0;
            default: printf("Invalid input");
        
    

入队时,我在以下行中发现了分段错误:(*pq)->next 在 enqueue() 函数中。我无法理解为什么会这样。是因为我接受了struct MinMax_PriorityQueue ** 类型的参数吗? 任何帮助表示赞赏。

【问题讨论】:

你能删除所有与问题无关的代码吗?如果问题出在enqueue,我们不需要显示和搜索代码。 pq=NULL; 正在覆盖您在前一行从malloc() 分配的变量。 摆脱它。 你希望它做什么:struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq)); pq=NULL; @500-InternalServerError 实际上是sizeof(**temp)) 【参考方案1】:

enqueue 函数中的(*pq)-&gt;next=temp; 导致段错误,因为*pq 在第一次调用时为 NULL。

您不应该注释掉对 NULL 的检查。你需要它.. 但喜欢

if(isEmpty(pq))
    *pq=temp;
    return;      // Add this

顺便说一句:

*pq 第一次调用enqueue 时为NULL 的原因是main 中的这段代码

struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
pq=NULL;    // You set pq back to NULL  (and leaks memory)

但你不应该一开始就在main 中使用malloc。只需这样做:

struct MinMax_PriorityQueue *pq=NULL;  // Empty queue

【讨论】:

那么你建议我删除malloc() 函数吗? @Jayajit 是的,绝对的。 @Jayajit 另请注意,即使使用此修复程序,您的 enqueue 函数也不会将第一个元素以外的其他元素排入队列。 Agian:修复 cout 注释的代码 我没明白你所说的“cout-commented code”是什么意思 注释掉的代码......我的意思是......你需要处理当前被注释掉的while部分。并添加一些优先级检查

以上是关于分段错误:在 C 中实现优先级队列的主要内容,如果未能解决你的问题,请参考以下文章

为啥在c++中实现基于类的优先级队列时需要重载operator<?

C++ 对象指针的优先级队列在运行时错误为无效堆

在我的二进制堆/优先级队列实现中实现删除时遇到问题

c struct queue error:“数组类型具有不完整的元素类型”

Prim算法优先队列

在C中制作一个计算PriorityQueue中元素数量的函数