• C语言程序中的内存结构数组


    我个人的理解:其实质,和Java里的Hash表有点类似。在C语言中是为了解决数组无法扩展的缺陷。

    例子:

    看 PostgreSQL对 VFD的处理:

    初始化:

    /*
     * Virtual File Descriptor array pointer and size.    This grows as
     * needed.    'File' values are indexes into this array.
     * Note that VfdCache[0] is not a usable VFD, just a list header.
     */
    static Vfd *VfdCache;
    static Size SizeVfdCache = 0;
    /*
     * InitFileAccess --- initialize this module during backend startup
     *
     * This is called during either normal or standalone backend start.
     * It is *not* called in the postmaster.
     */
    void
    InitFileAccess(void)
    {
        Assert(SizeVfdCache == 0);    /* call me only once */
    
        /* initialize cache header entry */
        ///####
        VfdCache = (Vfd *) malloc(sizeof(Vfd));
        if (VfdCache == NULL)
            ereport(FATAL,
                    (errcode(ERRCODE_OUT_OF_MEMORY),
                     errmsg("out of memory")));
    
        MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
        VfdCache->fd = VFD_CLOSED;
    
        SizeVfdCache = 1;
    
        /* register proc-exit hook to ensure temp files are dropped at exit */
        on_proc_exit(AtProcExit_Files, 0);
    }

    扩展:

    static File
    AllocateVfd(void)
    {
        Index        i;
        File        file;
    
        DO_DB(elog(LOG, "AllocateVfd. Size %lu", SizeVfdCache));
    
        Assert(SizeVfdCache > 0);    /* InitFileAccess not called? */
    
        if (VfdCache[0].nextFree == 0)
        {
            /*
             * The free list is empty so it is time to increase the size of the
             * array.  We choose to double it each time this happens. However,
             * there's not much point in starting *real* small.
             */
            Size        newCacheSize = SizeVfdCache * 2;
            Vfd           *newVfdCache;
    
            if (newCacheSize < 32)
                newCacheSize = 32;
    
            ////####
            /*
             * Be careful not to clobber VfdCache ptr if realloc fails.
             */
            newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
            if (newVfdCache == NULL)
                ereport(ERROR,
                        (errcode(ERRCODE_OUT_OF_MEMORY),
                         errmsg("out of memory")));
            VfdCache = newVfdCache;
    
            /*
             * Initialize the new entries and link them into the free list.
             */
            for (i = SizeVfdCache; i < newCacheSize; i++)
            {
                MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
                VfdCache[i].nextFree = i + 1;
                VfdCache[i].fd = VFD_CLOSED;
            }
            VfdCache[newCacheSize - 1].nextFree = 0;
            VfdCache[0].nextFree = SizeVfdCache;
    
            /*
             * Record the new size
             */
            SizeVfdCache = newCacheSize;
        }
    
        file = VfdCache[0].nextFree;
    
        VfdCache[0].nextFree = VfdCache[file].nextFree;
    
        return file;
    }
  • 相关阅读:
    读书思维导图
    19/12/19 最近计划
    搭建自己的终极框架
    Win10下安装erl和RabbitMQ踩坑【版本不兼容】
    这里的博客不再更新了,有兴趣的可以转移到我的新博客地址 https://spacesec.github.io/
    最新最全的sqlmap命令中文详解以及插件功能详解[最全]
    Listary:放弃笨拙且丑陋的文件查找系统吧
    自己写一个破解zip加密文件的脚本
    分享一下第一次和别人开发项目的心得
    如何进行git 的push操作
  • 原文地址:https://www.cnblogs.com/gaojian/p/3096170.html
Copyright © 2020-2023  润新知