zoukankan      html  css  js  c++  java
  • uc/os内存管理的理解

    OS_MEM   *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)   {

    ..............................................

    plink = (void **)addr;    /* Create linked list of free memory blocks当上述条件都得到满足时,所要建立的内存分区内的所有内存块链接成一个单向链表。这里之所以用单向链表,是因为在单向链表中插入和删除元素都是从链表的 顶端开始向下执行的。内存区可使用静态二维数组或者在初始化时使用malloc()建立,因为malloc()返回值为void*所以这里是 (void **)addr;其实此时plink里面存放的也是当前内存块的地址*/   

    pblk   = (INT8U *)addr + blksize; /*pblk指向将被释放的内存控制块的指针。如果在此处不是很理解,请参看谭浩强C语言的多维数组与指针一节。其实此时pblk就是链表的下一个内存块的地址*/   

        for (i = 0; i < (nblks - 1); i++) {               /*这里也体现了nblk应该大于等于2*/   

            *plink = (void *)pblk;  /*在plink所指向的地址内存入指针pblk,这样此时这个plink指向的单元的头

            四个字节中存入了链表的下一个内存块的地址。*/   

            plink   = (void **)pblk;    /* plink和pblk指向同一地址    (void **)pblk 这样转换了类型 但是pblk的

             值并不改变,于是这样把pblk的值赋给了plink*/   

            pblk    = pblk + blksize;   /*指针pblk指向地址(plbk + blksize);这一段程序建立了一个内存分区,该内

            存分区由nblks个大小为blksize的内存块组成.所有的内存块以单联表的形式连接在一起。单联表的指针域在每个内存块的头四个 字节内(一个指针占用四个字节).注意一个指针的大小决定于所用编译器 TC运行在16位模拟器中所以指针大小是16位即2字节   而 现在大多数编译器运行在32位模拟器中所以指针大小是32位即4字节。

    }   

    .................................................................

    }

    c语言不够扎实,这是网上找的解说,看了好久貌似懂了。

    其实就是 把pblk(一个地址)看成一个数,然后强制类型转换后赋给相应一级和二级指针,这样就形成了链表

    void   *OSMemGet (OS_MEM *pmem, INT8U *err)         /*传递给OSMemGet()函数的参数中的指针pmem,它指向希望从中非配到内存块 的内存分区。*/   

    {

    ................................

    if (pmem->OSMemNFree > 0) {    /* See if there are any free memory blocks;OSMemGet()要检查内存分区中是否有空余的内存块。*/   

        pblk    = pmem->OSMemFreeList;    /* Yes, point to next free memory block如果有空余内存块,那么其中第 1个内存块会从空余内存块链表中被删除*/   

        pmem->OSMemFreeList = *(void **)pblk;      /*       Adjust pointer to new free list此处为什么要用*(void **)pblk 的形式 网上众说纷纭,其实我觉的很简单,因为OSMemFreeList在定义的时候就定义成了void* 见UCOS_II.H文件 这里纯粹就是 为了统一类型作的强制转换类型而已,是一种编程的好习惯。当然还是应该格外注意void*的用法。*/   

             pmem->OSMemNFree--;    /*       One less memory block in this partition空余内存块链表会被更新,包括将链表头指针后移一个元素和将空余内存块数减一。*/   

             OS_EXIT_CRITICAL();   

             *err = OS_NO_ERR;                            

          return (pblk);   /*    Return memory block to caller将指向已分配的内存块的指针返回给用户程序。*/   

         }   

    ....................................

    }

    第一句:pmem->OSMemFreeList也指向空闲链表的起始地址,把这个起始赋给pblk

    第二句:即把pmem->OSMemFreeList(也即pblk)指向的地址中的内容(即下一内存块的地址)赋给pmem->OSMemFreeList

    难点就是 要搞清 地址 和地址中存的内容,即二级指针方面

    Live together,or Die alone!
  • 相关阅读:
    golang的select典型用法
    vscode配置git和提交代码到github教程
    VsCode中好用的git源代码管理插件GitLens
    GoMock框架使用指南
    golang对结构体排序,重写sort
    Go语言开发Prometheus Exporter示例
    golang 字符串拼接性能比较
    golang中的strings.Compare
    各大厂分布式链路跟踪系统架构对比
    NV triton启动方式说明
  • 原文地址:https://www.cnblogs.com/hzhida/p/2425169.html
Copyright © 2011-2022 走看看