You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言删除双向链表素数时无限输出随机值问题及修复

双向链表删除素数节点问题

我实现了一个双向链表,想要删除链表中所有值为素数的节点,但是运行代码时会无限输出随机值,问题出在删除素数的函数中,我自己找不到错误原因。

原始错误代码

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

struct node 
{
    int data;
    struct node *next;
    struct node *prev;
}*head=NULL;

int length(struct node *p)
{
    int len;
    while(p!=NULL)
    {
        len++;
        p = p->next;
    }
    return len;
}

void display(struct node *p)
{
    if(p == NULL)
    {
        printf("Linked List is empty\n");
    }
    else
    {
        printf("Linked List: ");
        while(p!=NULL)
        {
            printf("%d ", p->data);
            p = p->next;
        }
    }
}

void insert(struct node *p, int index, int x)
{
    struct node *t;
    if(index == 0)
    {
        t = (struct node *)malloc(sizeof(struct node));
        t->data = x;
        t->next = head;
        t->prev = NULL;
        if(head != NULL)
        {
            head->prev = t;
        }
        head = t;
    }
    else
    {
        t = (struct node *)malloc(sizeof(struct node));
        t->data = x;

        for(int i=0; i<index-1; i++)
        {
            p = p->next;
        }
        t->prev = p;
        t->next = p->next;
        if(p->next != NULL)
        {
            p->next->prev = t;
        }
        p->next = t;
    }
}

int checkprime(int n)
{
    int prime = 1;
    for(int i=2; i<n; i++)
    {
        if(n % 2 == 0)
        {
            prime = 0;
            break;
        }
    }
    if(prime == 0)
    {
        return 0; //非素数
    }
    else
    {
        return 1; //素数
    }
}

void delete_prime_number(struct node *p)
{
    struct node *q;
    while(p != NULL)
    {
        q = p;
        p = p->next;
        if((checkprime(q->data)) == 1)
        {
            free(q);
        }
    }
}

int main()
{
    insert(head, 0, 2);
    insert(head, 1, 3);
    insert(head, 2, 4);
    insert(head, 3, 7);
    insert(head, 4, 8);
    insert(head, 5, 12);
    insert(head, 6, 15);
    insert(head, 7, 23);
    display(head);
    delete_prime_number(head);
    display(head);
    return 0;
}

核心错误原因

  • 删除节点时仅释放了对应内存,没有调整前后节点的prev和next指针关联,导致链表出现大量野指针,遍历时访问已释放的内存就会输出随机值
  • 未处理头节点是素数的场景,头节点被释放后没有更新头指针指向,整个链表结构完全混乱
  • checkprime函数逻辑错误:判断条件写死为n%2==0,只能过滤偶数,所有奇数都会被误判为素数;同时没有处理n小于2的边界情况
  • length函数中计数变量len未初始化,返回的长度为随机垃圾值

修复后可运行代码

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

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

int length(struct node *p)
{
    int len = 0;
    while (p != NULL)
    {
        len++;
        p = p->next;
    }
    return len;
}

void display(struct node *p)
{
    if (p == NULL)
    {
        printf("Linked List is empty\n");
    }
    else
    {
        printf("Linked List: ");
        while (p != NULL)
        {
            printf("%d ", p->data);
            p = p->next;
        }
    }
}

void insert(struct node **p, int index, int x)
{
    struct node *t;
    
    if (index == 0)
    {
        t = (struct node *)malloc(sizeof(struct node));
        t->data = x;
        t->next = *p;
        t->prev = NULL;
        if ((*p) != NULL)
        {
            (*p)->prev = t;
        }
        (*p) = t;
    }
    else
    {
        t = (struct node *)malloc(sizeof(struct node));
        t->data = x;
        for (int i = 0; i < index - 1; i++)
        {
            if((*p) == NULL)
            {
                printf("Linked List is empty!\n");
            }
            else
            {
                p = &(*p)->next;
            }    
        }
        t->prev = (*p);
        t->next = (*p)->next;
        if ((*p)->next != NULL)
        {
            (*p)->next->prev = t;
        }
        (*p)->next = t;
    }
}

int checkprime(int n)
{
    int prime = 1;
    if(n == 0 || n == 1)
    {
        return 0;
    }
    else
    {
        for (int i = 2; i < n; i++)
        {
            if (n % i == 0)
            {
                prime = 0;
                break;
            }
        }
        if (prime == 0)
        {
            return 0; //非素数
        }
        else
        {
            return 1; //素数
        }
    }  
}

void delete_prime_number(struct node **p)
{
    while (*p != NULL)
    {
        if (checkprime((*p)->data) == 1)
        {
            struct node *q = *p;
            if ((*p)->next != NULL)
            {
                (*p)->next->prev = (*p)->prev;
            }
            *p = (*p)->next;
            free(q);
        }
        else
        {
            p = &(*p)->next;
        }
    }
}

int main()
{
    struct node *head = NULL;
    insert(&head, 0, 2);
    insert(&head, 1, 3);
    insert(&head, 2, 4);
    insert(&head, 3, 7);
    insert(&head, 4, 8);
    insert(&head, 5, 12);
    insert(&head, 6, 15);
    insert(&head, 7, 23);
    display(head);
    delete_prime_number(&head);
    printf("\n");
    display(head);
    return 0;
}

内容的提问来源于stack exchange,提问作者ranger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:06:02