<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                內存釋放的操作也是比較簡單的,LwIP是這樣子做的:它根據用戶釋放的內存塊地址,通過偏移mem結構體大小得到正確的內存塊起始地址,并且根據mem中保存的內存塊信息進行釋放、合并等操作,并將used字段清零,表示該內存塊未被使用。 LwIP為了防止內存碎片的出現,通過算法將內存相鄰的兩個空閑內存塊進行合并,在釋放內存塊的時候,如果內存塊與上一個或者下一個空閑內存塊在地址上是連續的,那么就將這兩個內存塊進行合并,其源碼具體見代碼清單 5-12。 ``` 1 2 void 3 mem_free(void *rmem) 4 { 5 struct mem *mem; 6 LWIP_MEM_FREE_DECL_PROTECT(); 7 8 if (rmem == NULL) (1) 9 { 10 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 11 LWIP_DBG_LEVEL_SERIOUS, 12 ("mem_free(p == NULL) was called.\n")); 13 return; 14 } 15 if ((((mem_ptr_t)rmem) & (MEM_ALIGNMENT - 1)) != 0) 16 { 17 LWIP_MEM_ILLEGAL_FREE("mem_free: sanity check alignment"); 18 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, 19 ("mem_free: sanity check alignment\n")); 20 /* protect mem stats from concurrent access */ 21 MEM_STATS_INC_LOCKED(illegal); 22 return; 23 } 24 25 mem = (struct mem *)(void *)((u8_t *)rmem - 26 (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET)); (2) 27 28 if ((u8_t *)mem < ram || 29 (u8_t *)rmem + MIN_SIZE_ALIGNED > (u8_t *)ram_end) (3) 30 { 31 LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory"); 32 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, 33 ("mem_free: illegal memory\n")); 34 /* protect mem stats from concurrent access */ 35 MEM_STATS_INC_LOCKED(illegal); 36 return; 37 } 38 39 /* protect the heap from concurrent access */ 40 LWIP_MEM_FREE_PROTECT(); 41 42 /* mem has to be in a used state */ 43 if (!mem->used) (4) 44 { 45 LWIP_MEM_ILLEGAL_FREE("mem_free: illegal \ 46 memory: double free"); 47 LWIP_MEM_FREE_UNPROTECT(); 48 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, 49 ("mem_free: illegal memory: double free?\n")); 50 /* protect mem stats from concurrent access */ 51 MEM_STATS_INC_LOCKED(illegal); 52 return; 53 } 54 55 if (!mem_link_valid(mem)) (5) 56 { 57 LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory:\ 58 non-linked: double free"); 59 LWIP_MEM_FREE_UNPROTECT(); 60 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, 61 ("mem_free: illegal memory: non-linked: double free?\n")); 62 /* protect mem stats from concurrent access */ 63 MEM_STATS_INC_LOCKED(illegal); 64 return; 65 } 66 67 /* mem is now unused. */ 68 mem->used = 0; (6) 69 70 if (mem < lfree) 71 { 72 /* the newly freed struct is now the lowest */ 73 lfree = mem; (7) 74 } 75 76 MEM_STATS_DEC_USED(used, mem->next - 77 (mem_size_t)(((u8_t *)mem - ram))); 78 79 /* finally, see if prev or next are free also */ 80 plug_holes(mem); (8) 81 82 MEM_SANITY(); 83 84 LWIP_MEM_FREE_UNPROTECT(); 85 } ``` * (1):如果釋放的地址為空,則直接返回。 * (2):對釋放的地址進行偏移,得到真正內存塊的起始地址。 * (3):判斷一下內存塊的起始地址是否合法,如果不合法則直接返回。 * (4):判斷一下內存塊是否被使用,如果是未使用的也直接返回。 * (5):判斷一下內存塊在鏈表中的連接是否正常,如果不正常也直接返回。 * (6):程序執行到這里,表示內存塊能正常釋放,就將used置0表示已經釋放了內存塊。 * (7):如果剛剛釋放的內存塊地址比lfree指向的內存塊地址低,則更新lfree指針。 * (8):調用plug_holes()函數嘗試進行內存塊合并,如果能合并則合并,該函數就是我們說的內存塊合并算法,只要新釋放的內存塊與上一個或者下一個空閑內存塊在地址上是連續的,則進行合并,該函數的代碼具體見代碼清單 5-13,該函數比較容易理解,就不做過多贅述。 ``` 1 static void 2 plug_holes(struct mem *mem) 3 { 4 struct mem *nmem; 5 struct mem *pmem; 6 7 LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); 8 LWIP_ASSERT("plug_holes: mem < ram_end", 9 (u8_t *)mem < (u8_t *)ram_end); 10 LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); 11 12 /* plug hole forward */ 13 LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", 14 mem->next <= MEM_SIZE_ALIGNED); 15 16 nmem = ptr_to_mem(mem->next); 17 if (mem != nmem && nmem->used == 0 && 18 (u8_t *)nmem != (u8_t *)ram_end) 19 { 20 /* if mem->next is unused and not end of ram, combine mem and mem->next */ 21 if (lfree == nmem) 22 { 23 lfree = mem; 24 } 25 mem->next = nmem->next; 26 if (nmem->next != MEM_SIZE_ALIGNED) 27 { 28 ptr_to_mem(nmem->next)->prev = mem_to_ptr(mem); 29 } 30 } 31 32 /* plug hole backward */ 33 pmem = ptr_to_mem(mem->prev); 34 if (pmem != mem && pmem->used == 0) 35 { 36 /* if mem->prev is unused, combine mem and mem->prev */ 37 if (lfree == mem) 38 { 39 lfree = pmem; 40 } 41 pmem->next = mem->next; 42 if (mem->next != MEM_SIZE_ALIGNED) 43 { 44 ptr_to_mem(mem->next)->prev = mem_to_ptr(pmem); 45 } 46 } 47 } ``` 對內存釋放函數的操作要非常小心,尤其是傳遞給函數的參數,該參數必須是內存申請返回的地址,這樣子才能保證系統根據該地址去尋找內存塊中的mem結構體,最終通過操作mem結構體才能實現內存塊的釋放操作,并且這樣子才有可能進行內存塊的合并,否則就沒法正常合并內存塊,還會把整個內存堆打亂,這樣子就會很容易產生內存碎片。 此外,用戶在申請內存的時候要注意及時釋放內存塊,否則就會造成內存泄漏,什么是內存泄漏呢?就是用戶在調用內存分配函數后,沒有及時或者進行錯誤的內存釋放操作,一次兩次這樣子的操作并沒有什么影響,如果用戶周期性調用mem_malloc()函數進行內存申請,并且在內存使用完的時候么有釋放,這樣子程序就會用完內存堆中的所有內存,最終導致內存耗盡無法申請內存,出現死機等現象。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看