c语言数据结构队列问题,出现nullptr,请问是哪里有问题呢


typedef int quint;
typedef struct qnode{
    quint data;
    struct qnode* next;
}qnode;

typedef struct qu {
    qnode * head;
    qnode* tail;
}qu;

void intqu(qu *q) {
    if(q == NULL)
    {
        exit(-1);
    }
    
        q->head = NULL;
        q->tail = NULL;
    
}

void pushqu(qu* q, quint x) {
    qnode* newnode = (qnode*)malloc(sizeof(qnode)); 
    if (newnode == NULL) {
        printf("内存分配不成功!\n");
    }
    else {
        newnode->data = x;
        newnode->next = NULL;
    }
        if (q->head == NULL) {
            q->head = q->tail = newnode;
        }
        else {
            q->tail->next = newnode;
            q->tail = newnode;
        }
    }


void popqu(qu* q) {
    if (q->head == NULL) {
        printf("删除失败,队列空");
    }
    else {
        qnode* tem = q->head->next;
        q->head = NULL;
        free(q->head);
        q->head = tem;
        if (q->head = NULL)
        {
            q->tail = NULL;
        }
    }
}

quint QueueFront(qu* qu)
{
    if (qu == NULL)
        return 0;
    else
    return qu->head->data;
};
quint QueueBack(qu* qu)
{
    if (qu == NULL)
        return 0;
    else
    return qu->tail->data;
};
int main() {
    qu q;
    intqu(&q);
    pushqu(&q, 1);
    pushqu(&q, 2);
    popqu(&q);//这里报错,说引发了异常: 读取访问权限冲突。q.head 是 nullptr。
    printf("%d", q.head->data);
    return 0;
    
}

52行改为if (q->head == NULL)

nullptr 在C语言中并不存在,这是C++11引入的新特性,表示空指针。在C语言中,可以使用宏定义 NULL 来表示空指针,NULL 的值为0。

如果在队列的实现中出现了nullptr,可能有以下几种情况:

  1. 在定义指针时没有初始化为NULL,导致其指向了随机的内存地址;
  2. 在使用指针时没有进行有效性检查,导致指针为NULL时仍然进行操作;
  3. 在指针赋值时没有判断原指针是否为NULL,导致新指针覆盖了原指针,导致原指针的值变为nullptr。

需要仔细排查代码,找出具体位置并进行修复。此外,建议在定义指针时都进行初始化,这样可以避免因为指针未初始化而导致的问题。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在 popqu 函数中,存在一个问题:

qnode* tem = q->head->next;
q->head = NULL;
free(q->head);
q->head = tem;
if (q->head = NULL)
{
    q->tail = NULL;
}

在这段代码中,第二行代码将 q->head 设置为 NULL,然后在第三行中尝试释放 NULL 指针所指向的内存,这是不正确的。这可能导致内存访问冲突和未定义行为。

您应该将第二行和第三行的代码调整为以下形式:

qnode* tem = q->head->next;
free(q->head);
q->head = tem;
if (q->head == NULL)
{
    q->tail = NULL;
}

在这种情况下,首先释放 q->head 指向的内存,然后将 q->head 指向下一个节点,从而避免了访问空指针的问题。

此外,在判断 q->head 是否为 NULL 的语句中,应该使用双等号(==)进行比较,而不是单等号(=),因为单等号会将 NULL 赋值给 q->head,从而导致程序逻辑错误。因此,应该将最后一行改为:

if (q->head == NULL)
{
    q->tail = NULL;
}

修改后的 popqu 函数如下所示:

void popqu(qu* q) {
    if (q->head == NULL) {
        printf("删除失败,队列空");
    }
    else {
        qnode* tem = q->head->next;
        free(q->head);
        q->head = tem;
        if (q->head == NULL)
        {
            q->tail = NULL;
        }
    }
}

修改后的代码应该可以正常运行了。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢