zoukankan      html  css  js  c++  java
  • NetBSD Make源代码阅读二:链表之创建与销毁

    1.创建链表

    /*-
     *-----------------------------------------------------------------------
     * Lst_Init --
     *    创建并初始化一个链表 
     *
     * 输入:
     *    circ    如果是循环链表则为TRUE     
     *
     * 结果:
     *    创建好的链表(空链表).
     *
     * 副作用:
     *    链表已经创建,还需要做啥?
     *
     *-----------------------------------------------------------------------
     */
    Lst
    Lst_Init(Boolean circ)
    {
        List    nList;          /* List为链表结构指针类型*/
    
        PAlloc (nList, List);    /*分配链表结构内存,并让nList指向该结构*/
    
        nList->firstPtr = NULL;     /*初始化链表结构各成员变量*/
        nList->lastPtr = NULL;
        nList->isOpen = FALSE;
        nList->isCirc = circ;
        nList->atEnd = Unknown;
    
        return (nList);           /*返回链表结构指针*/
    }

      其实,这个函数就是分配链表结构内存,然后初始化结构成员变量。值得注意的是,分配链表结构内存的操作PAlloc。

    /*
     * PAlloc (var, ptype) --
     *    分配 'ptype' 类型结构的内存,并把地址赋给变量 'var'
     */
    #define    PAlloc(var,ptype)    var = (ptype) bmake_malloc(sizeof *(var))
    /*
     * bmake_malloc --
     *    调用malloc分配内存,如果出错,打印错误信息到stderr并退出
     */
    void *
    bmake_malloc(size_t len)
    {
        void *p;
    
        if ((p = malloc(len)) == NULL)
            enomem();
        return(p);
    }

    2. 销毁链表

        链表结构分为两部分一个是链表头结构List,一个是其节点ListNode。而在ListNode中包含一个指向客户自定义数据的指针。下面这个函数,为了遍历各个节点方便,把最后一个节点的nextptr设成null,这主要针对循环列表。

      链表销毁的步骤:

      1.依次释放链表的节点,如果指定了freeProc,则调用它释放节点对应的客户数据

      2.然后释放链表头结构。

    /*-
     *-----------------------------------------------------------------------
     * Lst_Destroy --
     *    销毁链表并释放其所有资源。如果指定了freeProc ,则在每个节点释放前
     *    对其应用该函数。
     *    
     *
     * 返回值:
     *    无
     *
     * 副作用:
     *    所给的链表完全销毁
     *
     *-----------------------------------------------------------------------
     */
    void
    Lst_Destroy(Lst list, FreeProc *freeProc)
    {
        ListNode    ln;
        ListNode    tln = NULL;
    
        if (list == NULL)
        return;
    
        /* 为了让遍历更简单 */
        if (list->lastPtr != NULL)                    /×如果所给的链表不是空的×/
        list->lastPtr->nextPtr = NULL;      
        else {
        free(list);                                    /×释放链表头结构×/
        return;
        }
    
        if (freeProc) {
        for (ln = list->firstPtr; ln != NULL; ln = tln) {
             tln = ln->nextPtr;
             freeProc(ln->datum);    /×释放节点指向的数据*/
             free(ln);                      /*释放节点*/
        }
        } else {
        for (ln = list->firstPtr; ln != NULL; ln = tln) {
             tln = ln->nextPtr;
             free(ln);
        }
        }
    
        free(list);   / *释放链表头×/
    }
  • 相关阅读:
    不意外:Facebook上市遭遇滑铁卢
    最不浪漫的17个人生片段
    解決IE不能訪問ftp的問題
    關於Micrsoft.VisualBasic.dll中Strings.StrConv的第三個參數LocaleID引起的問題
    一個水平垂直的Div頁面效果
    常用的CSS命名规则[轉載]
    asp.net連接數據庫時出現問題的解決方法
    javascript訪問剪貼板的內容
    offsetTop、offsetLeft、offsetWidth、offsetHeight的用法[轉載]
    微软正版软件验证的手工解决方案
  • 原文地址:https://www.cnblogs.com/RbtreeLinux/p/3530441.html
Copyright © 2011-2022 走看看