虚空钻 2021-06-16 11:02 采纳率: 100%
浏览 170
已采纳

c语言指针为NULL出错

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

// 定义链队数据节点
typedef struct qnode
{
    int data;
    struct qnode *next;
}DataNode;

// 定义链队头结点
typedef struct 
{
    DataNode *front;
    DataNode *rear;
}LinkQuNode;

// 初始化队列
void InitQueue(LinkQuNode *q)
{
    q = (LinkQuNode *)malloc(sizeof(LinkQuNode));
    q -> front = q -> rear = NULL;
}

// 销毁队列
void DestroyQueue(LinkQuNode *q)
{
    DataNode *pre = q -> front, *p; // pre指向队首节点(除了队头节点的第一个节点)
    if(pre != NULL)
    {
        p = pre -> next;
        while(p != NULL)
        {
            free(p);
            pre = p; p = p -> next;
        }
        free(p);
    }
    free(q);
    printf("队列已销毁");
    return;
}

// 队列判空
void QueueEmpty(LinkQuNode *q)
{
    if(q -> front == NULL)
       printf("队列为空\n");
    else
       printf("队列不为空\n");
}

// 进队列
void enQueue(LinkQuNode *q, int e)
{
    DataNode *p;
    p = (DataNode *)malloc(sizeof(DataNode));
    p -> data = e;
    p -> next = NULL;
    if(q -> rear == NULL) // 当结点是队列中的第一个结点时
      q -> front = q -> rear = p;   // 队头结点和队尾结点同时指向p
    else
    {
        q -> rear -> next = p;
        q -> rear = p;
    }
}

// 出队列, 返回出队列的值e
int deQueue(LinkQuNode *q)
{
    DataNode *t;
    if(q -> rear == NULL) // 队列为空
    {
        printf("队列空\n");
        return 1;
    }
    t = q -> front;
    if(q -> front == q -> rear) // 队列中只有一个数据结点
       q -> front = q -> rear = NULL;
    else
    {
        q -> front = q -> front -> next;
    }
    printf("被删除的元素是:%d\n", t -> data);
    free(t);
    return 0;
}

// 入队功能函数
void pushQueue(LinkQuNode *q)
{
    int i;
    printf("输入要入队的数据:");
    scanf("%d", &i);
    enQueue(q, i);
    printf("入队成功");
}

int main()
{
    int menu;
    LinkQuNode *q;
    InitQueue(q);
    printf("1 入队列     2 出队列\n");
    printf("3 队列判空   4 销毁队列\n");
    printf("5 退出\n");
   
    while(1)
    {
        printf("请输入菜单号:");
        scanf("%d", &menu);
        if(menu == 5)
          break;
        switch(menu)
       {
          case 1: pushQueue(q); break;
          case 2: deQueue(q); break;
          case 3: QueueEmpty(q); break;
          case 4: DestroyQueue(q); break;
          default: printf("1\n");
       }
    }
    return 0;
    
}


这是代码和调试的结果,实在找不出错误的原因,请求大佬告知。

  • 写回答

4条回答 默认 最新

  • bostonAlen 2021-06-16 16:59
    关注


    这个问题的原因不是在在函数中开辟的空间地址离开函数就无效。

    用 malloc() 函数申请的内存地址离开函数后还是有效,需要主动用 free() 函数释放才会无效。

    这段代码出问题的原因在于,传入到 InitQueue() 函数的参数类型不对。下面这种写法,传入到该函数的 q指针参数是传值的方式,在 InitQueue() 函数内部并不能修改外部 q 指针变量的值。

    void InitQueue(LinkQuNode *q)

    即,在你的 main() 函数的下面语句中,LinkQuNode *q 这个变量的值并不会因为执行 InitQueue(q); 语句而改变。执行 InitQueue(q); 语句后,q这个变量值还是没有初始化,并没有指向 malloc() 分配出来的内存地址。

    LinkQuNode *q;
    InitQueue(q);


    如果你想要修改外部这个q变量的值,要把 InitQueue函数的参数类型改成 void InitQueue(LinkQuNode **q),然后再该函数里面用 *q 来为它赋值。

    把 q = (LinkQuNode *)malloc(sizeof(LinkQuNode));//分配空间 提到主函数有效,就是因为这会真正为 q变量赋值。

    你可以用 printf("q: %p", &q); 语句打印 L 指针变量的地址来查看 InitQueue() 函数内外 L 的地址,看是否一样。

    对于 InitQueue(LinkQuNode *q) 这种函数来说,可以用 q 指针来修改 q 指向的内存地址的值,但是这个 L 是形参,修改 q 本身的值,并不影响外面实参的值。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加
  • ¥15 用ns3仿真出5G核心网网元
  • ¥15 matlab答疑 关于海上风电的爬坡事件检测
  • ¥88 python部署量化回测异常问题