【转】LwIP 协议栈源码分析(读书笔记)--内存管理--动态内存堆(HEAP)分配策略源码

<article>
        <div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post">
                    <div class="markdown_views">
                <p>本章分析动态内存堆(HEAP)的第一种分配策略,承接上篇文章 <br>
 <a href="https://blog.csdn.net/guozhongwei1/article/details/80064011#t1" rel="nofollow" target="_blank">LwIP 协议栈源码分析(读书笔记)–内存管理–机制策略分析</a></p>



<h1 id="组织形式"><a name="t0"></a>组织形式:</h1>

<p><img src="https://img-blog.csdn.net/20180425095530787?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3pob25nd2VpMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述" title=""></p>

<p><img src="https://img-blog.csdn.net/2018042509582090?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3pob25nd2VpMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述" title=""></p>

<h1 id="memc源码解析如下"><a name="t1"></a>mem.c源码解析如下:</h1>



<h2 id="meminit"><a name="t2"></a>mem_init():</h2>



<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-javadoc">/**
 * Zero the heap and initialize start, end and lowest-free
 */</span>
<span class="hljs-keyword">void</span>
mem_init(<span class="hljs-keyword">void</span>)
{
  struct mem *mem;

  LWIP_ASSERT(<span class="hljs-string">"Sanity check alignment"</span>,
    (SIZEOF_STRUCT_MEM &amp; (MEM_ALIGNMENT-<span class="hljs-number">1</span>)) == <span class="hljs-number">0</span>);<span class="hljs-comment">//内存大小对齐及检测</span>

  <span class="hljs-comment">/* align the heap */</span>
  ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER);<span class="hljs-comment">//堆地址 对齐</span>
  <span class="hljs-comment">/* initialize the start of the heap==初始化堆链表的头结点 */</span>
  mem = (struct mem *)(<span class="hljs-keyword">void</span> *)ram;<span class="hljs-comment">//指针类型强转为链表</span>
  mem-&gt;next = MEM_SIZE_ALIGNED;<span class="hljs-comment">//#define MEM_SIZE  16000 //内存堆heap大小</span>
  mem-&gt;prev = <span class="hljs-number">0</span>;
  mem-&gt;used = <span class="hljs-number">0</span>;
  <span class="hljs-comment">/* initialize the end of the heap==初始化堆链表的结束结点 */</span>
  ram_end = (struct mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[MEM_SIZE_ALIGNED];
  ram_end-&gt;used = <span class="hljs-number">1</span>;<span class="hljs-comment">//指明用户不可用</span>
  ram_end-&gt;next = MEM_SIZE_ALIGNED;
  ram_end-&gt;prev = MEM_SIZE_ALIGNED;

  <span class="hljs-comment">/* initialize the lowest-free pointer to the start of the heap==
  **指向最低空闲块的指针,这用于更快的搜索 */</span>
  lfree = (struct mem *)(<span class="hljs-keyword">void</span> *)ram;

  MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);

  <span class="hljs-keyword">if</span>(sys_mutex_new(&amp;mem_mutex) != ERR_OK) {<span class="hljs-comment">//new一个互斥信号量 mem_mutex,名字看出,内存管理专用</span>
    LWIP_ASSERT(<span class="hljs-string">"failed to create mem_mutex"</span>, <span class="hljs-number">0</span>);
  }
}
}</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li></ul></pre>

<p>内存对齐操作:SIZEOF_STRUCT_MEM</p>



<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> SIZEOF_STRUCT_MEM    LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))</span></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre>

<p>关于字节对齐算法:LWIP_MEM_ALIGN_SIZE() <br>
参见:<a href="https://blog.csdn.net/guozhongwei1/article/details/50434733" rel="nofollow" target="_blank">字节对齐算法</a> <br>
进行此项操作的理由:lwip按自己的内存对齐规则管理维护内部的数据,不受编译器的对齐规则影响。</p>



<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-javadoc">/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array== 堆起始地址*/</span>
<span class="hljs-keyword">static</span> u8_t *ram;
<span class="hljs-javadoc">/** the last entry, always unused! ==最后一项,不会被使用*/</span>
<span class="hljs-keyword">static</span> struct mem *ram_end;
<span class="hljs-javadoc">/** pointer to the lowest free block, this is used for faster search *==指向最低空闲块的指针,这用于更快的搜索*/</span>
<span class="hljs-keyword">static</span> struct mem *lfree;</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre>



<h2 id="memmalloc"><a name="t3"></a>mem_malloc( ) :</h2>



<pre class="prettyprint" name="code"><code class="hljs fsharp has-numbering">
/**
 * Adam's mem_malloc() plus solution <span class="hljs-keyword">for</span> bug #<span class="hljs-number">17922</span>
 * Allocate a block <span class="hljs-keyword">of</span> memory <span class="hljs-keyword">with</span> a minimum <span class="hljs-keyword">of</span> 'size' bytes.
 *
 * @param size is the minimum size <span class="hljs-keyword">of</span> the requested block <span class="hljs-keyword">in</span> bytes.
 * @<span class="hljs-keyword">return</span> pointer <span class="hljs-keyword">to</span> allocated memory <span class="hljs-keyword">or</span> NULL <span class="hljs-keyword">if</span> no free memory was found.
 *
 * Note that the returned value will always be aligned (<span class="hljs-keyword">as</span> defined by MEM_ALIGNMENT).
 */
<span class="hljs-keyword">void</span> *
mem_malloc(mem_size_t size)
{
  mem_size_t ptr, ptr2;
  <span class="hljs-keyword">struct</span> mem *mem, *mem2;
#<span class="hljs-keyword">if</span> LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
  u8_t local_mem_free_count = <span class="hljs-number">0</span>;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
  LWIP_MEM_ALLOC_DECL_PROTECT();<span class="hljs-comment">//</span>

  <span class="hljs-keyword">if</span> (size == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> NULL;
  }

  /* Expand the size <span class="hljs-keyword">of</span> the allocated memory region so that we can
     adjust <span class="hljs-keyword">for</span> alignment. */
  size = LWIP_MEM_ALIGN_SIZE(size);<span class="hljs-comment">//对齐</span>

  <span class="hljs-keyword">if</span>(size &lt; MIN_SIZE_ALIGNED) {
    /* every data block must be at least MIN_SIZE_ALIGNED long */
    size = MIN_SIZE_ALIGNED;
  }

  <span class="hljs-keyword">if</span> (size &gt; MEM_SIZE_ALIGNED) {
    <span class="hljs-keyword">return</span> NULL;
  }

  /* protect the heap from concurrent access */
  sys_mutex_lock(&amp;mem_mutex);<span class="hljs-comment">//保护堆不受并发访问</span>
  LWIP_MEM_ALLOC_PROTECT();
#<span class="hljs-keyword">if</span> LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT<span class="hljs-comment">//未定义,无do--while</span>
  /* run <span class="hljs-keyword">as</span> long <span class="hljs-keyword">as</span> a mem_free disturbed mem_malloc <span class="hljs-keyword">or</span> mem_trim */
  <span class="hljs-keyword">do</span> {
    local_mem_free_count = <span class="hljs-number">0</span>;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */

    /* Scan through the heap searching <span class="hljs-keyword">for</span> a free block that is big enough,
     * beginning <span class="hljs-keyword">with</span> the lowest free block.
     */
    <span class="hljs-keyword">for</span> (ptr = (mem_size_t)((u8_t *)lfree - ram)/*上次分配内存后的最低lfree节点地址*/; ptr &lt; MEM_SIZE_ALIGNED - size/*分配后剩余大小*/;
         ptr = ((<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr])-&gt;next/*指向下一个结点*/) {
      mem = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr];

      <span class="hljs-keyword">if</span> ((!mem-&gt;used) &amp;&amp;<span class="hljs-comment">//该块内存未使用</span>
          (mem-&gt;next - (ptr + SIZEOF_STRUCT_MEM)) &gt;= size/*相应的内存大小够用*/) {
        /* mem is not used <span class="hljs-keyword">and</span> at least perfect fit is possible:
         * mem-&gt;next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' <span class="hljs-keyword">of</span> mem */

        <span class="hljs-keyword">if</span> (mem-&gt;next - (ptr + SIZEOF_STRUCT_MEM) &gt;= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {<span class="hljs-comment">//是否能够拆分该节点的数据块</span>
          /* (<span class="hljs-keyword">in</span> addition <span class="hljs-keyword">to</span> the above, we test <span class="hljs-keyword">if</span> another <span class="hljs-keyword">struct</span> mem (SIZEOF_STRUCT_MEM) containing
           * at least MIN_SIZE_ALIGNED <span class="hljs-keyword">of</span> data also fits <span class="hljs-keyword">in</span> the 'user data space' <span class="hljs-keyword">of</span> 'mem')
           * -&gt; split large block, create empty remainder,
           * remainder must be large enough <span class="hljs-keyword">to</span> contain MIN_SIZE_ALIGNED data: <span class="hljs-keyword">if</span>
           * mem-&gt;next - (ptr + (<span class="hljs-number">2</span>*SIZEOF_STRUCT_MEM)) == size,
           * <span class="hljs-keyword">struct</span> mem would fit <span class="hljs-keyword">in</span> but no data between mem2 <span class="hljs-keyword">and</span> mem2-&gt;next
           * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
           *       region that couldn't hold data, but <span class="hljs-keyword">when</span> mem-&gt;next gets freed,
           *       the <span class="hljs-number">2</span> regions would be combined, resulting <span class="hljs-keyword">in</span> more free memory
           */
          ptr2 = ptr + SIZEOF_STRUCT_MEM + size;<span class="hljs-comment">//分割内存后,剩余部分的地址</span>
          /* create mem2 <span class="hljs-keyword">struct</span><span class="hljs-comment">//新建一个结点维护剩余的内存 */</span>
          mem2 = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr2];
          mem2-&gt;used = <span class="hljs-number">0</span>;
          mem2-&gt;next = mem-&gt;next;
          mem2-&gt;prev = ptr;
          /* <span class="hljs-keyword">and</span> insert it between mem <span class="hljs-keyword">and</span> mem-&gt;next */
          mem-&gt;next = ptr2;
          mem-&gt;used = <span class="hljs-number">1</span>;

          <span class="hljs-keyword">if</span> (mem2-&gt;next != MEM_SIZE_ALIGNED) {<span class="hljs-comment">//非最后一个结点(中间结点)</span>
            ((<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[mem2-&gt;next])-&gt;prev = ptr2;<span class="hljs-comment">//更新后边的prev地址,完成链表的插入</span>
          }
          MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
        } <span class="hljs-keyword">else</span> {<span class="hljs-comment">//不能够拆分,更新used成员为已使用</span>
          /* (a mem2 <span class="hljs-keyword">struct</span> does no fit into the user data space <span class="hljs-keyword">of</span> mem <span class="hljs-keyword">and</span> mem-&gt;next will always
           * be used at this point: <span class="hljs-keyword">if</span> not we have <span class="hljs-number">2</span> unused structs <span class="hljs-keyword">in</span> a row, plug_holes should have
           * take care <span class="hljs-keyword">of</span> this).
           * -&gt; near fit <span class="hljs-keyword">or</span> excact fit: <span class="hljs-keyword">do</span> not split, no mem2 creation
           * also can't move mem-&gt;next directly behind mem, since mem-&gt;next
           * will always be used at this point!
           */
          mem-&gt;used = <span class="hljs-number">1</span>;
          MEM_STATS_INC_USED(used, mem-&gt;next - (mem_size_t)((u8_t *)mem - ram));
        }
        <span class="hljs-keyword">if</span> (mem == lfree) {<span class="hljs-comment">//查找空闲的 没有被使用的节点,方便下次调用</span>
          <span class="hljs-keyword">struct</span> mem *cur = lfree;
          /* Find next free block after mem <span class="hljs-keyword">and</span> update lowest free pointer */
          <span class="hljs-keyword">while</span> (cur-&gt;used &amp;&amp; cur != ram_end) {
#<span class="hljs-keyword">if</span> LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
            mem_free_count = <span class="hljs-number">0</span>;
            LWIP_MEM_ALLOC_UNPROTECT();
            /* prevent high interrupt latency... */
            LWIP_MEM_ALLOC_PROTECT();
            <span class="hljs-keyword">if</span> (mem_free_count != <span class="hljs-number">0</span>) {
              /* If mem_free <span class="hljs-keyword">or</span> mem_trim have run, we have <span class="hljs-keyword">to</span> restart since they
                 could have altered our current <span class="hljs-keyword">struct</span> mem <span class="hljs-keyword">or</span> lfree. */
              goto mem_malloc_adjust_lfree;
            }
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
            cur = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[cur-&gt;next];
          }
          lfree = cur;<span class="hljs-comment">//更新lfree</span>
          LWIP_ASSERT(<span class="hljs-string">"mem_malloc: !lfree-&gt;used"</span>, ((lfree == ram_end) || (!lfree-&gt;used)));
        }
        LWIP_MEM_ALLOC_UNPROTECT();
        sys_mutex_unlock(&amp;mem_mutex);<span class="hljs-comment">//解锁内存互斥信号量</span>
        LWIP_ASSERT(<span class="hljs-string">"mem_malloc: allocated memory not above ram_end."</span>,
         (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size &lt;= (mem_ptr_t)ram_end);<span class="hljs-comment">//边界检查</span>
        LWIP_ASSERT(<span class="hljs-string">"mem_malloc: allocated memory properly aligned."</span>,
         ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == <span class="hljs-number">0</span>);<span class="hljs-comment">//对齐检查</span>
        LWIP_ASSERT(<span class="hljs-string">"mem_malloc: sanity check alignment"</span>,
          (((mem_ptr_t)mem) &amp; (MEM_ALIGNMENT-<span class="hljs-number">1</span>)) == <span class="hljs-number">0</span>);<span class="hljs-comment">//对齐检查</span>

        <span class="hljs-keyword">return</span> (u8_t *)mem + SIZEOF_STRUCT_MEM;
      }
    }
#<span class="hljs-keyword">if</span> LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
    /* <span class="hljs-keyword">if</span> we got interrupted by a mem_free, <span class="hljs-keyword">try</span> again */
  } <span class="hljs-keyword">while</span>(local_mem_free_count != <span class="hljs-number">0</span>);
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, (<span class="hljs-string">"mem_malloc: could not allocate %"</span>S16_F<span class="hljs-string">" bytes\n"</span>, (s16_t)size));
  MEM_STATS_INC(err);
  LWIP_MEM_ALLOC_UNPROTECT();
  sys_mutex_unlock(&amp;mem_mutex);
  <span class="hljs-keyword">return</span> NULL;
}
</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li></ul></pre>

<p>流程描述: <br>
从lfree空闲块节点开始,确认used成员,比较节点内存时候够用,否则向后查找。 <br>
一旦找到,判断下能够分割, <br>
能分割,意味着需要插入一个节点到链表。 <br>
否则,更新used成员为已使用。 <br>
找到合适的内存后,更新lfree空闲块儿指针; <br>
检查对齐, <br>
return 数据内存地址(需要去掉维护链表节点的内存)</p>



<h2 id="memcalloc"><a name="t4"></a>mem_calloc( ):</h2>



<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-javadoc">/**
 * Contiguously allocates enough space for count objects that are size bytes
 * of memory each and returns a pointer to the allocated memory.
 *
 * The allocated memory is filled with bytes of value zero.
 *
 *<span class="hljs-javadoctag"> @param</span> count number of objects to allocate
 *<span class="hljs-javadoctag"> @param</span> size size of the objects to allocate
 *<span class="hljs-javadoctag"> @return</span> pointer to allocated memory / NULL pointer if there is an error
 */</span>
<span class="hljs-keyword">void</span> *mem_calloc(mem_size_t count, mem_size_t size)
{
  <span class="hljs-keyword">void</span> *p;

  <span class="hljs-comment">/* allocate 'count' objects of size 'size' */</span>
  p = mem_malloc(count * size);<span class="hljs-comment">//分配内存</span>
  <span class="hljs-keyword">if</span> (p) {
    <span class="hljs-comment">/* zero the memory */</span>
    memset(p, <span class="hljs-number">0</span>, count * size);<span class="hljs-comment">//清零</span>
  }
  <span class="hljs-keyword">return</span> p;
}</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li></ul></pre>

<p>对mem_malloc进行封装====清零已分配的内存。</p>



<h2 id="memfree"><a name="t5"></a>mem_free():</h2>



<pre class="prettyprint" name="code"><code class="hljs r has-numbering">
/**
 * Put a struct mem back on the heap
 *
 * @param rmem is the data portion of a struct mem as returned by a previous
 *             call to mem_malloc()
 */
void
mem_free(void *rmem)
{
  struct mem *mem;
  LWIP_MEM_FREE_DECL_PROTECT();

  <span class="hljs-keyword">if</span> (rmem == <span class="hljs-literal">NULL</span>) {
    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, (<span class="hljs-string">"mem_free(p == NULL) was called.\n"</span>));
    <span class="hljs-keyword">return</span>;
  }
  LWIP_ASSERT(<span class="hljs-string">"mem_free: sanity check alignment"</span>, (((mem_ptr_t)rmem) &amp; (MEM_ALIGNMENT-<span class="hljs-number">1</span>)) == <span class="hljs-number">0</span>);

  LWIP_ASSERT(<span class="hljs-string">"mem_free: legal memory"</span>, (u8_t *)rmem &gt;= (u8_t *)ram &amp;&amp;
    (u8_t *)rmem &lt; (u8_t *)ram_end);

  <span class="hljs-keyword">if</span> ((u8_t *)rmem &lt; (u8_t *)ram || (u8_t *)rmem &gt;= (u8_t *)ram_end) {
    SYS_ARCH_DECL_PROTECT(lev);
    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, (<span class="hljs-string">"mem_free: illegal memory\n"</span>));
    /* protect mem stats from concurrent access */
    SYS_ARCH_PROTECT(lev);
    MEM_STATS_INC(illegal);
    SYS_ARCH_UNPROTECT(lev);
    <span class="hljs-keyword">return</span>;
  }
  /* protect the heap from concurrent access */
  LWIP_MEM_FREE_PROTECT();
  /* Get the corresponding struct mem <span class="hljs-keyword">...</span> */
  mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);//确定相关链表节点
  /* <span class="hljs-keyword">...</span> which has to be <span class="hljs-keyword">in</span> a used state <span class="hljs-keyword">...</span> */
  LWIP_ASSERT(<span class="hljs-string">"mem_free: mem-&gt;used"</span>, mem-&gt;used);
  /* <span class="hljs-keyword">...</span> and is now unused. */
  mem-&gt;used = <span class="hljs-number">0</span>;//更新该块内存为未使用

  <span class="hljs-keyword">if</span> (mem &lt; lfree) {//更新lfree
    /* the newly freed struct is now the lowest */
    lfree = mem;
  }

  MEM_STATS_DEC_USED(used, mem-&gt;<span class="hljs-keyword">next</span> - (mem_size_t)(((u8_t *)mem - ram)));

  /* finally, see <span class="hljs-keyword">if</span> prev or <span class="hljs-keyword">next</span> are free also */
  plug_holes(mem);//整合相邻的节点,满足条件则合并
<span class="hljs-comment">#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT</span>
  mem_free_count = <span class="hljs-number">1</span>;
<span class="hljs-comment">#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */</span>
  LWIP_MEM_FREE_UNPROTECT();
}
</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li></ul></pre>

<p>释放内存,并整合相邻的资源。</p>



<h2 id="memtrim"><a name="t6"></a>mem_trim():</h2>



<pre class="prettyprint" name="code"><code class="hljs fsharp has-numbering">/**
 * Shrink memory returned by mem_malloc().
 *
 * @param rmem pointer <span class="hljs-keyword">to</span> memory allocated by mem_malloc the is <span class="hljs-keyword">to</span> be shrinked
 * @param newsize required size after shrinking (needs <span class="hljs-keyword">to</span> be smaller than <span class="hljs-keyword">or</span>
 *                equal <span class="hljs-keyword">to</span> the previous size)
 * @<span class="hljs-keyword">return</span> <span class="hljs-keyword">for</span> compatibility reasons: is always == rmem, at the moment
 *         <span class="hljs-keyword">or</span> NULL <span class="hljs-keyword">if</span> newsize is &gt; old size, <span class="hljs-keyword">in</span> which case rmem is NOT touched
 *         <span class="hljs-keyword">or</span> freed!
 */
<span class="hljs-keyword">void</span> *
mem_trim(<span class="hljs-keyword">void</span> *rmem, mem_size_t newsize)
{
  mem_size_t size;
  mem_size_t ptr, ptr2;
  <span class="hljs-keyword">struct</span> mem *mem, *mem2;
  /* <span class="hljs-keyword">use</span> the FREE_PROTECT here: it protects <span class="hljs-keyword">with</span> sem OR SYS_ARCH_PROTECT */
  LWIP_MEM_FREE_DECL_PROTECT();

  /* Expand the size <span class="hljs-keyword">of</span> the allocated memory region so that we can
     adjust <span class="hljs-keyword">for</span> alignment. */
  newsize = LWIP_MEM_ALIGN_SIZE(newsize);

  <span class="hljs-keyword">if</span>(newsize &lt; MIN_SIZE_ALIGNED) {
    /* every data block must be at least MIN_SIZE_ALIGNED long */
    newsize = MIN_SIZE_ALIGNED;
  }

  <span class="hljs-keyword">if</span> (newsize &gt; MEM_SIZE_ALIGNED) {
    <span class="hljs-keyword">return</span> NULL;
  }

  LWIP_ASSERT(<span class="hljs-string">"mem_trim: legal memory"</span>, (u8_t *)rmem &gt;= (u8_t *)ram &amp;&amp;
   (u8_t *)rmem &lt; (u8_t *)ram_end);

  <span class="hljs-keyword">if</span> ((u8_t *)rmem &lt; (u8_t *)ram || (u8_t *)rmem &gt;= (u8_t *)ram_end) {
    SYS_ARCH_DECL_PROTECT(lev);
    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, (<span class="hljs-string">"mem_trim: illegal memory\n"</span>));
    /* protect mem stats from concurrent access */
    SYS_ARCH_PROTECT(lev);
    MEM_STATS_INC(illegal);
    SYS_ARCH_UNPROTECT(lev);
    <span class="hljs-keyword">return</span> rmem;
  }
  /* Get the corresponding <span class="hljs-keyword">struct</span> mem ... */
  mem = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);<span class="hljs-comment">//获取输入的rmem内存地址的链表节点</span>
  /* ... <span class="hljs-keyword">and</span> its offset pointer */
  ptr = (mem_size_t)((u8_t *)mem - ram);<span class="hljs-comment">//索引</span>

  size = mem-&gt;next - ptr - SIZEOF_STRUCT_MEM;<span class="hljs-comment">//节点内存块的大小</span>
  LWIP_ASSERT(<span class="hljs-string">"mem_trim can only shrink memory"</span>, newsize &lt;= size);
  <span class="hljs-keyword">if</span> (newsize &gt; size) {
    /* not supported */
    <span class="hljs-keyword">return</span> NULL;
  }
  <span class="hljs-keyword">if</span> (newsize == size) {
    /* No change <span class="hljs-keyword">in</span> size, simply <span class="hljs-keyword">return</span> */
    <span class="hljs-keyword">return</span> rmem;
  }

  /* protect the heap from concurrent access */
  LWIP_MEM_FREE_PROTECT();

  mem2 = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[mem-&gt;next];<span class="hljs-comment">//下一个节点</span>
  <span class="hljs-keyword">if</span>(mem2-&gt;used == <span class="hljs-number">0</span>) {<span class="hljs-comment">//空闲,则剩余部分与下一个节点合并</span>
    /* The next <span class="hljs-keyword">struct</span> is unused, we can simply move it at little */
    mem_size_t next;
    /* remember the old next pointer */
    next = mem2-&gt;next;
    /* create <span class="hljs-keyword">new</span> <span class="hljs-keyword">struct</span> mem which is moved directly after the shrinked mem */
    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
    <span class="hljs-keyword">if</span> (lfree == mem2) {
      lfree = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr2];
    }
    mem2 = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr2];
    mem2-&gt;used = <span class="hljs-number">0</span>;
    /* restore the next pointer */
    mem2-&gt;next = next;
    /* link it back <span class="hljs-keyword">to</span> mem */
    mem2-&gt;prev = ptr;
    /* link mem <span class="hljs-keyword">to</span> it */
    mem-&gt;next = ptr2;
    /* last thing <span class="hljs-keyword">to</span> restore linked list: <span class="hljs-keyword">as</span> we have moved mem2,
     * <span class="hljs-keyword">let</span> 'mem2-&gt;next-&gt;prev' point <span class="hljs-keyword">to</span> mem2 again. but only <span class="hljs-keyword">if</span> mem2-&gt;next is not
     * the <span class="hljs-keyword">end</span> <span class="hljs-keyword">of</span> the heap */
    <span class="hljs-keyword">if</span> (mem2-&gt;next != MEM_SIZE_ALIGNED) {
      ((<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[mem2-&gt;next])-&gt;prev = ptr2;
    }
    MEM_STATS_DEC_USED(used, (size - newsize));
    /* no need <span class="hljs-keyword">to</span> plug holes, we've already <span class="hljs-keyword">done</span> that */
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED &lt;= size) {<span class="hljs-comment">//不能合并到下一个节点,新建节点并插入链表</span>
    /* Next <span class="hljs-keyword">struct</span> is used but there's room <span class="hljs-keyword">for</span> another <span class="hljs-keyword">struct</span> mem <span class="hljs-keyword">with</span>
     * at least MIN_SIZE_ALIGNED <span class="hljs-keyword">of</span> data.
     * Old size ('size') must be big enough <span class="hljs-keyword">to</span> contain at least 'newsize' plus a <span class="hljs-keyword">struct</span> mem
     * ('SIZEOF_STRUCT_MEM') <span class="hljs-keyword">with</span> some data ('MIN_SIZE_ALIGNED').
     * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
     *       region that couldn't hold data, but <span class="hljs-keyword">when</span> mem-&gt;next gets freed,
     *       the <span class="hljs-number">2</span> regions would be combined, resulting <span class="hljs-keyword">in</span> more free memory */
    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
    mem2 = (<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[ptr2];
    <span class="hljs-keyword">if</span> (mem2 &lt; lfree) {
      lfree = mem2;
    }
    mem2-&gt;used = <span class="hljs-number">0</span>;
    mem2-&gt;next = mem-&gt;next;
    mem2-&gt;prev = ptr;
    mem-&gt;next = ptr2;
    <span class="hljs-keyword">if</span> (mem2-&gt;next != MEM_SIZE_ALIGNED) {
      ((<span class="hljs-keyword">struct</span> mem *)(<span class="hljs-keyword">void</span> *)&amp;ram[mem2-&gt;next])-&gt;prev = ptr2;
    }
    MEM_STATS_DEC_USED(used, (size - newsize));
    /* the original mem-&gt;next is used, so no need <span class="hljs-keyword">to</span> plug holes! */
  }
  /* <span class="hljs-keyword">else</span> {
    next <span class="hljs-keyword">struct</span> mem is used but size between mem <span class="hljs-keyword">and</span> mem2 is not big enough
    <span class="hljs-keyword">to</span> create another <span class="hljs-keyword">struct</span> mem
    -&gt; don't <span class="hljs-keyword">do</span> anyhting. 
    -&gt; the remaining space stays unused since it is too small
  } */
#<span class="hljs-keyword">if</span> LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
  mem_free_count = <span class="hljs-number">1</span>;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
  LWIP_MEM_FREE_UNPROTECT();
  <span class="hljs-keyword">return</span> rmem;
}
</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li></ul></pre>

<p>功能:缩小已申请内存的大小,参数rmem务必小于参数newsize <br>
应用场景:减小调用mem_malloc()函数申请的内存大小, <br>
从功能上看,调用mem_malloc(500)申请了500字节,不想用那么多了,还不想mem_free()释放,在当前申请到的内存基础上,重新申请一块更小的。相当于将当前的内存再次分割或者合并到相邻的内存。</p>            </div>
            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
                </div>
            </article>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值