前言
最近使用RT-Thread的动态内存管理:rt_malloc rt_free,总结一下使用心得。
掌握动态内存的申请与释放。
问题描述
使用rt_malloc 一个字节后,发现,内存消耗:24字节!
使用rt_free 一个动态申请的buf后,buf指针还在!
问题分析
验证平台:Pandora
STM32L4平台,RT-Thread 4.0.3
测试函数:
rt_uint8_t *ptr_buf = RT_NULL;
void mem_malloc_test(int argc, char **argv)
{
rt_uint32_t buf_len = 0x00;
if (argc >= 2)
{
buf_len = atoi(argv[1]);
ptr_buf = rt_malloc(buf_len);
rt_kprintf("%s:malloc len=%d
", __func__, buf_len);
rt_kprintf("%s: ptr=%p
", __func__, ptr_buf);
}
else
{
rt_kprintf("help: mem_malloc_test 3
");
}
}
void mem_free_test(void)
{
if (ptr_buf != RT_NULL)
{
rt_free(ptr_buf);
rt_kprintf("%s: free OK!
", __func__);
rt_kprintf("%s: ptr=%p
", __func__, ptr_buf);
}
else
{
rt_kprintf("%s: error! buffer is null!
", __func__);
}
}
MSH_CMD_EXPORT(mem_malloc_test, memory malloc test);
MSH_CMD_EXPORT(mem_free_test, memory free test);
如下表:
申请1~12个字节,都会占用:24字节。
申请的字节数,不是4字节对齐的,依旧与4字节对齐的占用相同的大小。如申请13~16字节,占用内存都是28。
申请大于12字节的内存,如13、16、100、1K、10K、40K等,内存管理部分额外占用均为:12字节。
rt_malloc 与 rt_free成对使用,不会造成内存的泄漏
rt_free后,free的buffer没有了,但是,buffer指针值并不改变!
重点问题
申请内存后,rt_free这个buf,buf指针还是存在的。所以rt_free后,需要手动赋值buf为null。
rt_free后,buf指针还在,若不手动把这个buf指针赋值为null,多次free这个buf,会出现意想不到的后果!
以下,我用一个全局的指针,申请内存后,多次free(free后,指针没有手动改为null)
备注:经过验证,发现字节意外【关闭了RT_ASSERT功能】,否则,重复rt_free,是会出现ASSERT断言的!!
以下数据,仅供参考,意思是:rt_free后,需要手动把指针改为null,不可重复free!
msh />free
total memory: 82256
used memory : 24564
maximum allocated memory: 27572
msh />mem_mal
mem_malloc_test
msh />mem_malloc_test 12
mem_malloc_test:malloc len=12
mem_malloc_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 24588
maximum allocated memory: 27572
msh />mem_free_test
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28788
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28764 /* 内存在变小!!!! */
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28740 /* 内存在变小!!!! */
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28692
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28668 /* 内存在变小!!!! */
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28644 /* 内存在变小!!!! */
maximum allocated memory: 29604
msh />mem_free_test
to free a bad data block:
mem: 0x20003e98, used flag: 0, magic code: 0x1ea0
mem_free_test: free OK!
mem_free_test: ptr=20003ea4
msh />free
total memory: 82256
used memory : 28620 /* 内存在变小!!!! */
maximum allocated memory: 29604
msh />
发现一个全局的指针,申请一次内存后,多次free,虽然报错,但依旧可以free
问题的根本原因:【关闭了RT_ASSERT功能】
总结
正确使用rt_malloc 与 rt_free,成对出现
静态内存虽然好用,但一直占用内存,所以,一些不定长的数据接收buffer,可以使用动态内存管理。
注意free后的内存,指针地址还在,如果为全局的指针,最好free后,手动改为null。