RT-Thread 入门学习笔记 - menuconfig Kconfig的使用
RT-Thread 入门学习笔记 - 熟悉动态内存申请与释放
RT-Thread 入门学习笔记 - 查看线程栈的地址
RT-Thread 入门学习笔记 - 解决RT_ASSERT失效的问题
前言
- 最近使用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\n", __func__, buf_len);
rt_kprintf("%s: ptr=%p\n", __func__, ptr_buf);
}
else
{
rt_kprintf("help: mem_malloc_test 3\n");
}
}
void mem_free_test(void)
{
if (ptr_buf != RT_NULL)
{
rt_free(ptr_buf);
rt_kprintf("%s: free OK!\n", __func__);
rt_kprintf("%s: ptr=%p\n", __func__, ptr_buf);
}
else
{
rt_kprintf("%s: error! buffer is null!\n", __func__);
}
}
MSH_CMD_EXPORT(mem_malloc_test, memory malloc test);
MSH_CMD_EXPORT(mem_free_test, memory free test);
如下表:
init | rt_malloc | rt_free | buf_len | total size | diff |
---|---|---|---|---|---|
28788 | 28812 | 28788 | 1 | 24 | 23 |
28788 | 28812 | 28788 | 4 | 24 | 20 |
28788 | 28812 | 28788 | 8 | 24 | 16 |
28788 | 28812 | 28788 | 10 | 24 | 14 |
28788 | 28812 | 28788 | 11 | 24 | 13 |
28788 | 28812 | 28788 | 12 | 24 | 12 |
28788 | 28816 | 28788 | 13 | 28 | 15 |
28788 | 28816 | 28788 | 16 | 28 | 12 |
28788 | 28820 | 28788 | 20 | 32 | 12 |
28788 | 28824 | 28788 | 24 | 36 | 12 |
28788 | 28900 | 28788 | 100 | 112 | 12 |
28788 | 39040 | 28788 | 10240 | 10252 | 12 |
28788 | 69760 | 28788 | 40960 | 40972 | 12 |
- 申请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_malloc 与 rt_free,成对出现!!
- 静态内存虽然好用,但一直占用内存,所以,一些不定长的数据接收buffer,可以使用动态内存管理。
- 注意free后的内存,指针地址还在,如果为全局的指针,最好free后,手动改为null。