嵌入式学习小组
直播中

王飞

7年用户 1113经验值
私信 关注

存储管理的例程KEY_1释放完以后最多只能按2次是为什么?

存储管理的例程(例12-1)里面,为什么第一次按KEY_UP最多可以按五次,KEY_1释放完以后,之后KEY_UP就最多只能按2次了?否者程序就卡死了。KEY_2申请外部SRAM时的现象也一样,求大神解答为什么?

回帖(4)

王慕涛

2020-4-30 08:55:40
内存没释放!导致内存泄露!
举报

刘鹏

2020-4-30 09:15:56
怎么突然就变成最佳答案了?虽然前面KEY_UP按了5次,但是都按KEY_1释放完了呀,之后KEY_UP才按了3次程序就死掉了,理论上都没有内存泄露
举报

郭雨桐

2020-4-30 09:39:16
用串口接一下发现释放缓存的函数并没有什么卵用,KEY_UP按了两次后,再按两次KEY_1,之后再按KEY_UP,他申请的地址不是重新来过的。这样释放OSMemPut()函数就没什么卵用了..
举报

何夏庄

2020-4-30 09:48:45
视频上说是内存泄漏,上面的那位回答者也说是内存泄漏,解释太过于笼统!导致内存泄漏的原因有很多,该处具体是怎么导致的没有说。我的观点如下。
首先我们知道,每次申请一个存储块,FreeListPtr便会指向下一个存储块的首地址,同时返回申请到的存储块的首地址。
你看代码:                switch(key)
                {
                        case WKUP_PRES:                //按下KEY_UP键
                                internal_buf=OSMemGet((OS_MEM*)&INTERNAL_MEM,
                                                                      (OS_ERR*)&err);
                                if(err == OS_ERR_NONE) //内存申请成功
                                {
                                ......
每次申请一个一个存储块,返回申请到的存储块的首地址都是放在变量internal_buf中。
(注意:在释放存储块的时候,我们必须知道该存储块的首地址。)
于是,如果我们连续申请存储块,当我们申请第一个存储块的时候,其首地址放在internal_buf中;紧接着我们不释放它,而是继续申请下一个存储块,其首地址仍然放到internal_buf中。看到没,第一个存储块的首地址被覆盖掉了!!!
我们不知道第一个存储块的首地址,所以不可能再将第一个存储块释放掉了。(你可以通过串口打印来验证,你连续申请几个存储块,再按键释放,会发现地址不会再返回去了)
所以,当我们用发烧友给的代码连续申请几个存储块后,仅能释放最后申请的存储块。(注意在释放存储块时,并没有改变internal_buf变量,只是调整FreeListPtr指针,让其指向上一个存储块)。
解决方案!!!
定义不同的变量去存放申请到的存储块的首地址即可,而不是向发烧友的例程代码里把所有申请到的存储块的首地址都放在internal_buf变量中。
                                OSMemPut((OS_MEM*        )&INTERNAL_MEM,                //释放内存
                                                         (void*                )【这里放哪个存储块的首地址,就会释放哪个存储块】,
                                                         (OS_ERR*         )&err);
另外注意,比如我们在连续申请了三个存储块后,得到这三个存储块的首地址,我们放在数组internal_buf[2]中,我们在释放存储块的时候,也要按顺序释放,也就是先释放internal_buf[2]指向的存储块,再释放internal_buf[1]指向的存储块,最后释放internal_buf[0]指向的存储块。这样FreeListPtr指针才能最终指向第一个存储块,回到申请存储块之初的状态!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分