OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10386|回复: 8

存储管理的例程(例12-1)里面,为什么第一次按KEY_UP最多可以按五次,KEY_1释放完以后,之后KEY_UP就最多只能按2次了?

[复制链接]

13

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-11-16
在线时间
8 小时
发表于 2016-6-21 22:14:12 | 显示全部楼层 |阅读模式
3金钱
存储管理的例程(例12-1)里面,为什么第一次按KEY_UP最多可以按五次,KEY_1释放完以后,之后KEY_UP就最多只能按2次了?否者程序就卡死了。KEY_2申请外部SRAM时的现象也一样,求大神解答为什么?

最佳答案

查看完整内容[请看2#楼]

内存没释放!导致内存泄露!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-6-21 22:14:13 | 显示全部楼层
内存没释放!导致内存泄露!
回复

使用道具 举报

13

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-11-16
在线时间
8 小时
 楼主| 发表于 2016-6-23 11:42:53 | 显示全部楼层
怎么突然就变成最佳答案了?虽然前面KEY_UP按了5次,但是都按KEY_1释放完了呀,之后KEY_UP才按了3次程序就死掉了,理论上都没有内存泄露
回复

使用道具 举报

13

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-11-16
在线时间
8 小时
 楼主| 发表于 2016-6-23 11:43:12 | 显示全部楼层
zuozhongkai 发表于 2016-6-21 22:14
内存没释放!导致内存泄露!

怎么突然就变成最佳答案了?虽然前面KEY_UP按了5次,但是都按KEY_1释放完了呀,之后KEY_UP才按了3次程序就死掉了,理论上都没有内存泄露
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-6-23 12:51:19 | 显示全部楼层
本帖最后由 zuozhongkai 于 2016-6-23 12:53 编辑
AUGUS 发表于 2016-6-23 11:43
怎么突然就变成最佳答案了?虽然前面KEY_UP按了5次,但是都按KEY_1释放完了呀,之后KEY_UP才按了3次程序 ...

按一次KEY_UP申请一次内存就得按一次KEY_1释放一次内存,要是连续按了3次KEY_UP结果就只按了一次KEY_1肯定就会造成内存泄漏!你是不是连续按了5次KEY_UP然后又连续按了5次KEY_1,这样是只释放了一个内存,其他4个就泄漏了,看代码!
开往春天的手扶拖拉机
回复

使用道具 举报

13

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-11-16
在线时间
8 小时
 楼主| 发表于 2016-6-25 18:57:28 | 显示全部楼层
zuozhongkai 发表于 2016-6-23 12:51
按一次KEY_UP申请一次内存就得按一次KEY_1释放一次内存,要是连续按了3次KEY_UP结果就只按了一次KEY_1肯 ...

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

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2018-4-23
在线时间
3 小时
发表于 2018-4-29 17:13:14 | 显示全部楼层
本帖最后由 ChenTianyu 于 2018-4-29 17:23 编辑

视频上说是内存泄漏,上面的那位回答者也说是内存泄漏,解释太过于笼统!导致内存泄漏的原因有很多,该处具体是怎么导致的没有说。我的观点如下。
首先我们知道,每次申请一个存储块,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指针才能最终指向第一个存储块,回到申请存储块之初的状态!
回复

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2018-9-30
在线时间
39 小时
发表于 2019-8-10 11:19:50 | 显示全部楼层
ChenTianyu 发表于 2018-4-29 17:13
视频上说是内存泄漏,上面的那位回答者也说是内存泄漏,解释太过于笼统!导致内存泄漏的原因有很多,该处具 ...

正解!
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2023-1-25
在线时间
5 小时
发表于 2023-2-26 12:31:28 | 显示全部楼层
我也遇见同样的问题。
后来我用串口跟踪过。
是正点原子提供的函数,逻辑上错误。

我分析过程如下:
当你按wakeup 按键5次之后,指针为intenal_buf=null。  
这时你再按key0时,不会在这行内存释放这个函数了
key0_press:
  if(intenal_buf!=null)
{
    OSMemput(......)
}

   仅供参考
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 07:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表