🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
同样的,内存释放函数也非常简单的,只需要把使用完毕的内存添加到对应内存池中的空闲内存块链表即可,只不过释放内存有两个参数,一个是POOL的类型,还有就是内存块的起始地址,源码具体见代码清单 5‑8 ``` 1 void 2 memp_free(memp_t type, void *mem) 3 { 4 LWIP_ERROR("memp_free: type < MEMP_MAX", 5 (type < MEMP_MAX), return;); 6 7 if (mem == NULL) 8 { 9 return; 10 } 11 do_memp_free_pool(memp_pools[type], mem); 12 } 13 14 static void 15 do_memp_free_pool(const struct memp_desc *desc, void *mem) 16 { 17 struct memp *memp; 18 SYS_ARCH_DECL_PROTECT(old_level); 19 20 LWIP_ASSERT("memp_free: mem properly aligned", 21 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); 22 23 /* cast through void* to get rid of alignment warnings */ 24 memp = (struct memp *)(void *)((u8_t *)mem - MEMP_SIZE); (1) 25 26 SYS_ARCH_PROTECT(old_level); 27 28 memp->next = *desc->tab; (2) 29 *desc->tab = memp; (3) 30 31 SYS_ARCH_UNPROTECT(old_level); 32 33 } ``` * (1):根据内存块的地址偏移得到内存块的起始地址,因为前面也说了,内存块中有一部分内容是内存分配器操作的,所以需要进行偏移。 * (2): 内存块的下一个就是链表中的第一个空闲内存块。 * (3):将内存块插入到对应内存池的*desc->tab中。 LwIP对内存池的设计,采用了很多巧妙的地方,特别是对编译全局变量的过程,根据用户配置的宏定义决定是否编译进去。而且,内存池还采用内存池描述表进行管理系统中所有的内存池,在用户需要某种类型的内存块时候,就直接将其需要的类型传递进去就能得到对应大小的内存块,分配的方式是非常方便并且高效的。