Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
内存释放_free
rt_free卡死问题!
发布于 2021-02-19 20:26:29 浏览:1427
订阅该版
rt_free有时候会卡死在`RT_ASSERT((((rt_ubase_t)rmem) & (ALIGN_SIZE - 1)) == 0);`,偶尔出一次吧。代码是我移植的之前工程的,用作裸机用。
查看更多
aozima
2021-02-20
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
说明你free的地址,并不是你malloc出来的结果呗。 检查你的应用程序吧,可以把全部`malloc/free`的地址都打印出来。
2
个回答
默认排序
按发布时间排序
春和景明
2021-02-19
这家伙很懒,什么也没写!
![捕获.PNG](https://oss-club.rt-thread.org/uploads/20210219/a4e55d0f55e68e07cff732d9f450ebdb.png) ```c #define MEM_GLOBALS #include "mem.h" #include "config.h" #include "service.h" /* #define RT_MEM_DEBUG */ #define RT_MEM_STATS #define HEAP_MAGIC 0x1ea0 struct heap_mem { /* magic and used flag */ rt_uint16_t magic; rt_uint16_t used; rt_size_t next, prev; }; /** pointer to the heap: for alignment, heap_ptr is now a pointer instead of an array */ static rt_uint8_t *heap_ptr; /** the last entry, always unused! */ static struct heap_mem *heap_end; #define MIN_SIZE 12 #define MIN_SIZE_ALIGNED RT_ALIGN(MIN_SIZE, ALIGN_SIZE) #define SIZEOF_STRUCT_MEM RT_ALIGN(sizeof(struct heap_mem), ALIGN_SIZE) static struct heap_mem *lfree; /* pointer to the lowest free block */ static rt_size_t mem_size_aligned; #ifdef RT_MEM_STATS static rt_size_t used_mem, max_mem; #endif static void plug_holes(struct heap_mem *mem) { struct heap_mem *nmem; struct heap_mem *pmem; RT_ASSERT((uint8_t *)mem >= heap_ptr); RT_ASSERT((uint8_t *)mem < (uint8_t *)heap_end); RT_ASSERT(mem->used == 0); /* plug hole forward */ nmem = (struct heap_mem *)&heap_ptr[mem->next]; if (mem != nmem && nmem->used == 0 && (rt_uint8_t *)nmem != (rt_uint8_t *)heap_end) { /* if mem->next is unused and not end of heap_ptr, * combine mem and mem->next */ if (lfree == nmem) { lfree = mem; } mem->next = nmem->next; ((struct heap_mem *)&heap_ptr[nmem->next])->prev = (rt_uint8_t *)mem - heap_ptr; } /* plug hole backward */ pmem = (struct heap_mem *)&heap_ptr[mem->prev]; if (pmem != mem && pmem->used == 0) { /* if mem->prev is unused, combine mem and mem->prev */ if (lfree == mem) { lfree = pmem; } pmem->next = mem->next; ((struct heap_mem *)&heap_ptr[mem->next])->prev = (rt_uint8_t *)pmem - heap_ptr; } } /** * @ingroup SystemInit * * This function will initialize system heap memory. * * @param begin_addr the beginning address of system heap memory. * @param end_addr the end address of system heap memory. */ void rt_system_heap_init(void *begin_addr, void *end_addr) { struct heap_mem *mem; rt_ubase_t begin_align = RT_ALIGN((rt_ubase_t)begin_addr, ALIGN_SIZE); rt_ubase_t end_align = RT_ALIGN_DOWN((rt_ubase_t)end_addr, ALIGN_SIZE); /* alignment addr */ if ((end_align > (2 * SIZEOF_STRUCT_MEM)) && ((end_align - 2 * SIZEOF_STRUCT_MEM) >= begin_align)) { /* calculate the aligned memory size */ mem_size_aligned = end_align - begin_align - 2 * SIZEOF_STRUCT_MEM; } else { rt_kprintf("mem init, error begin address 0x%x, and end address 0x%x\n", (rt_ubase_t)begin_addr, (rt_ubase_t)end_addr); return; } /* point to begin address of heap */ heap_ptr = (rt_uint8_t *)begin_align; DEBUG_LOG(DEBUG_MEM, ("mem init, heap begin address 0x%x, size %d\n", (rt_ubase_t)heap_ptr, mem_size_aligned)); /* initialize the start of the heap */ mem = (struct heap_mem *)heap_ptr; mem->magic = HEAP_MAGIC; mem->next = mem_size_aligned + SIZEOF_STRUCT_MEM; mem->prev = 0; mem->used = 0; /* initialize the end of the heap */ heap_end = (struct heap_mem *)&heap_ptr[mem->next]; heap_end->magic = HEAP_MAGIC; heap_end->used = 1; heap_end->next = mem_size_aligned + SIZEOF_STRUCT_MEM; heap_end->prev = mem_size_aligned + SIZEOF_STRUCT_MEM; /* initialize the lowest-free pointer to the start of the heap */ lfree = (struct heap_mem *)heap_ptr; } /** * @addtogroup MM */ /**@{*/ /** * Allocate a block of memory with a minimum of 'size' bytes. * * @param size is the minimum size of the requested block in bytes. * * @return pointer to allocated memory or NULL if no free memory was found. */ void *rt_malloc(rt_size_t size) { rt_size_t ptr, ptr2; struct heap_mem *mem, *mem2; if (size == 0) return RT_NULL; if (size != RT_ALIGN(size, ALIGN_SIZE)) DEBUG_LOG(DEBUG_MEM, ("malloc size %d, but align to %d\n", size, RT_ALIGN(size, ALIGN_SIZE))); else DEBUG_LOG(DEBUG_MEM, ("malloc size %d\n", size)); /* alignment size */ size = RT_ALIGN(size, ALIGN_SIZE); if (size > mem_size_aligned) { DEBUG_LOG(DEBUG_MEM, ("no memory\n")); return RT_NULL; } /* every data block must be at least MIN_SIZE_ALIGNED long */ if (size < MIN_SIZE_ALIGNED) size = MIN_SIZE_ALIGNED; /* take memory semaphore */ //take heap_sem时长为forever for (ptr = (rt_uint8_t *)lfree - heap_ptr; ptr < mem_size_aligned - size; ptr = ((struct heap_mem *)&heap_ptr[ptr])->next) //在 for 循环中遍历寻找合适的内存资源。 { mem = (struct heap_mem *)&heap_ptr[ptr]; if ((!mem->used) && (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { /* mem is not used and at least perfect fit is possible: * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { /* (in addition to the above, we test if another struct heap_mem (SIZEOF_STRUCT_MEM) containing * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') * -> split large block, create empty remainder, * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, * struct heap_mem would fit in but no data between mem2 and mem2->next * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty * region that couldn't hold data, but when mem->next gets freed, * the 2 regions would be combined, resulting in more free memory */ /*(除了上面的内容,我们测试是否另一个至少包含 struct heap_mem(SIZEOF_STRUCT_MEM) *MIN_SIZE_ALIGNED 数据也适合'用户数据空间 mem 的大小) * -> 拆分大块,创建空余数,余数必须足够大才能包含 MIN_SIZE_ALIGNED 数据: *if mem-> next - (ptr +(2 * SIZEOF_STRUCT_MEM))== size, *struct heap_mem 适合但 mem2 和 mem2-> next 之间没有数据 *@todo 我们可以省略 MIN_SIZE_ALIGNED。 我们会创建一个空的内存块 *虽然无法保存数据的区域,但是当 mem-> next 被释放时,两个区域将合并, *从而产生更多的可用内存 */ ptr2 = ptr + SIZEOF_STRUCT_MEM + size; /* create mem2 struct */ mem2 = (struct heap_mem *)&heap_ptr[ptr2]; mem2->magic = HEAP_MAGIC; mem2->used = 0; mem2->next = mem->next; mem2->prev = ptr; /* and insert it between mem and mem->next */ mem->next = ptr2; mem->used = 1; if (mem2->next != mem_size_aligned + SIZEOF_STRUCT_MEM) { ((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2; } #ifdef RT_MEM_STATS used_mem += (size + SIZEOF_STRUCT_MEM); if (max_mem < used_mem) max_mem = used_mem; #endif } else { /* (a mem2 struct does no fit into the user data space of mem and mem->next will always * be used at this point: if not we have 2 unused structs in a row, plug_holes should have * take care of this). * -> near fit or excact fit: do not split, no mem2 creation * also can't move mem->next directly behind mem, since mem->next * will always be used at this point! */ mem->used = 1; #ifdef RT_MEM_STATS used_mem += mem->next - ((rt_uint8_t *)mem - heap_ptr); if (max_mem < used_mem) max_mem = used_mem; #endif } /* set memory block magic */ mem->magic = HEAP_MAGIC; if (mem == lfree) { /* Find next free block after mem and update lowest free pointer */ while (lfree->used && lfree != heap_end) lfree = (struct heap_mem *)&heap_ptr[lfree->next]; RT_ASSERT(((lfree == heap_end) || (!lfree->used))); } //释放heap_sem信号量 RT_ASSERT((rt_ubase_t)mem + SIZEOF_STRUCT_MEM + size <= (rt_ubase_t)heap_end); RT_ASSERT((rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM) % ALIGN_SIZE == 0); RT_ASSERT((((rt_ubase_t)mem) & (ALIGN_SIZE - 1)) == 0); DEBUG_LOG(DEBUG_MEM, ("allocate memory at 0x%x, size: %d\n", (rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM), (rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - heap_ptr)))); /* return the memory data except mem struct */ return (rt_uint8_t *)mem + SIZEOF_STRUCT_MEM; } } //释放heap_sem return RT_NULL; } /** * This function will change the previously allocated memory block. * * @param rmem pointer to memory allocated by rt_malloc * @param newsize the required new size * * @return the changed memory block address */ void *rt_realloc(void *rmem, rt_size_t newsize) { rt_size_t size; rt_size_t ptr, ptr2; struct heap_mem *mem, *mem2; void *nmem; /* alignment size */ newsize = RT_ALIGN(newsize, ALIGN_SIZE); if (newsize > mem_size_aligned) { DEBUG_LOG(DEBUG_MEM, ("realloc: out of memory\n")); return RT_NULL; } else if (newsize == 0) { //rt_free(rmem); return RT_NULL; } /* allocate a new memory block */ if (rmem == RT_NULL) return rt_malloc(newsize); //rt_sem_take(&heap_sem, RT_WAITING_FOREVER); if ((rt_uint8_t *)rmem < (rt_uint8_t *)heap_ptr || (rt_uint8_t *)rmem >= (rt_uint8_t *)heap_end) { /* illegal memory */ // rt_sem_release(&heap_sem); return rmem; } mem = (struct heap_mem *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM); ptr = (rt_uint8_t *)mem - heap_ptr; size = mem->next - ptr - SIZEOF_STRUCT_MEM; if (size == newsize) { /* the size is the same as */ //rt_sem_release(&heap_sem); return rmem; } if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) { /* split memory block */ #ifdef RT_MEM_STATS used_mem -= (size - newsize); #endif ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; mem2 = (struct heap_mem *)&heap_ptr[ptr2]; mem2->magic = HEAP_MAGIC; mem2->used = 0; mem2->next = mem->next; mem2->prev = ptr; #ifdef RT_USING_MEMTRACE rt_mem_setname(mem2, " "); #endif mem->next = ptr2; if (mem2->next != mem_size_aligned + SIZEOF_STRUCT_MEM) { ((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2; } plug_holes(mem2); //rt_sem_release(&heap_sem); return rmem; } //rt_sem_release(&heap_sem); /* expand memory */ nmem = rt_malloc(newsize); if (nmem != RT_NULL) /* check memory */ { rt_memcpy(nmem, rmem, size < newsize ? size : newsize); rt_free(rmem); } return nmem; } /** * This function will contiguously allocate 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. * * @param count number of objects to allocate * @param size size of the objects to allocate * * @return pointer to allocated memory / NULL pointer if there is an error */ void *rt_calloc(rt_size_t count, rt_size_t size) { void *p; /* allocate 'count' objects of size 'size' */ p = rt_malloc(count * size); /* zero the memory */ if (p) rt_memset(p, 0, count * size); return p; } /** * This function will release the previously allocated memory block by * rt_malloc. The released memory block is taken back to system heap. * * @param rmem the address of memory which will be released */ void rt_free(void *rmem) { struct heap_mem *mem; if (rmem == RT_NULL) return; RT_ASSERT((((rt_ubase_t)rmem) & (ALIGN_SIZE - 1)) == 0); RT_ASSERT((rt_uint8_t *)rmem >= (rt_uint8_t *)heap_ptr && (rt_uint8_t *)rmem < (rt_uint8_t *)heap_end); if ((rt_uint8_t *)rmem < (rt_uint8_t *)heap_ptr || (rt_uint8_t *)rmem >= (rt_uint8_t *)heap_end) { DEBUG_LOG(DEBUG_MEM, ("illegal memory\n")); return; } /* Get the corresponding struct heap_mem ... */ mem = (struct heap_mem *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM); DEBUG_LOG(DEBUG_MEM, ("release memory 0x%x, size: %d\n", (rt_ubase_t)rmem, (rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - heap_ptr)))); /* protect the heap from concurrent access */ //rt_sem_take(&heap_sem, RT_WAITING_FOREVER); /* ... which has to be in a used state ... */ if (!mem->used || mem->magic != HEAP_MAGIC) { rt_kprintf("to free a bad data block:\n"); rt_kprintf("mem: 0x%08x, used flag: %d, magic code: 0x%04x\n", mem, mem->used, mem->magic); } RT_ASSERT(mem->used); RT_ASSERT(mem->magic == HEAP_MAGIC); /* ... and is now unused. */ mem->used = 0; mem->magic = HEAP_MAGIC; if (mem < lfree) { /* the newly freed struct is now the lowest */ lfree = mem; } #ifdef RT_MEM_STATS used_mem -= (mem->next - ((rt_uint8_t *)mem - heap_ptr)); #endif /* finally, see if prev or next are free also */ plug_holes(mem); //rt_sem_release(&heap_sem); } #ifdef RT_MEM_STATS void rt_memory_info(rt_uint32_t *total, rt_uint32_t *used, rt_uint32_t *max_used) { if (total != RT_NULL) *total = mem_size_aligned; if (used != RT_NULL) *used = used_mem; if (max_used != RT_NULL) *max_used = max_mem; } void list_mem(void) { rt_kprintf("total memory: %d bytes.\n", mem_size_aligned); rt_kprintf("used memory : %d bytes.\n", used_mem); rt_kprintf("maximum allocated memory: %d bytes.\n", max_mem); } #endif /**@}*/ ``` 小弟实在想不到,为啥了。特此求教。
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
春和景明
这家伙很懒,什么也没写!
提问
46
回答
48
被采纳
0
关注TA
发私信
相关问题
1
free a bad data block导致机器死机问题咨询
2
rt_free 返回plug_holes ASSERT错误
3
软件包ota_downloader的http_ota解析导致内存释放断言
4
关于rt_free 挂掉问题
5
对已删除的线程如何重新创建?
6
dataqueue内存泄漏
7
rt_free释放内存错误
8
rt_free()处理片外的SRAM时会崩溃
9
RT-Thread Studio创建Nano项目,添加HEAP支持后,编译出错
10
内存使用如何查看 free命令查看的内存大小是否正确
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部