以下是经过优化后的代码,并修复了代码中的问题:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include "kernel_list.h"


typedef struct node
{
    char *name;
    int time;

    struct list_head list;
}listnode,*linklist;

linklist init_list()
{
    linklist head = calloc(1,sizeof(listnode));

    if(head==NULL)
    {
        perror("内存分配失败!");
        exit(1);
    }
    INIT_LIST_HEAD(&head->list);
    return head;
}

linklist new_node(char *name,int time)
{
    linklist new = calloc(1,sizeof(listnode));

    if(new==NULL)
    {
        perror("内存分配失败!");
        exit(1);
    }
    new->name=name;
    new->time=time;
    INIT_LIST_HEAD(&new->list);
    return new;
}


void show(linklist head)
{
    linklist pos;
    list_for_each_entry(pos,&head->list.next,list)
    {
        printf("%s  %d\n",pos->name,pos->time);
    }

}


int main()
{
    //内核链表初始化
    linklist head=init_list();

    //打开,读取'record.txt'文件,写入内核链表中
    FILE *fp=fopen("record.txt","r");
    if(ferror(fp))
    {
        perror("文件打开失败!");
        exit(0);
    }
    int i =1;
    while(1)
    {
        char name_buf[20];
        int time_buf;

        fscanf(fp,"%s %d",name_buf,&time_buf);
        // char flag;
        // while(flag!='\n')  flag=fgetc(fp);

        linklist new=new_node(name_buf,time_buf);
        list_add_tail(&(new->list),&(head->list));
        
        if(feof(fp)) break;

        
    }
    show(head);
    fclose(fp); // 关闭文件指针

    // 释放内存
    linklist pos, n;
    list_for_each_entry_safe(pos, n, &head->list, list) {
        free(pos->name);
        list_del(&pos->list);
        free(pos);
    }
    free(head);

    return 0;
}

代码优化和问题分析

  1. 内存分配错误: 在函数 init_list()new_node() 中,使用 calloc() 动态分配内存后,需要进行内存分配成功的判断。如果分配失败,则返回 NULL 并打印错误信息,避免程序崩溃。

  2. 链表遍历错误: 在函数 show() 中,使用 list_for_each_entry() 遍历链表时,应该从 head->list.next 开始遍历,而不是从 head->list 开始遍历。

  3. 资源泄露: 在函数 main() 中,没有关闭打开的文件指针 fp,可能导致文件资源泄露。在程序结束前,使用 fclose(fp) 关闭文件指针。

  4. 内存泄露: 在函数 main() 中,没有释放动态分配的内存,可能导致内存泄露。使用 list_for_each_entry_safe 遍历链表并释放每个节点的内存,最后释放链表的头节点。

其他优化建议

  • 使用 const 修饰 name_buf 数组,防止其在函数内部被意外修改。
  • 可以使用 fgets() 读取文件内容,避免 fscanf() 潜在的缓冲区溢出风险。
  • 考虑使用 struct 结构体来封装节点数据,提高代码的可读性和可维护性。

通过以上优化和问题分析,可以提高代码的可靠性和安全性,避免内存泄漏和资源泄露问题。同时,代码结构也更加合理,可读性更强。

C语言内核链表实现:优化与分析

原文地址: https://www.cveoy.top/t/topic/qmT8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录