OpenEdv-开源电子网

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

请教1个内存释放的问题。

[复制链接]

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
发表于 2015-7-23 16:25:03 | 显示全部楼层 |阅读模式
5金钱
请教1个问题,在“例11-1 UCOSIII消息传递”中,有个函数:
//定时器1的回调函数
void tmr1_callback(void *p_tmr,void *p_arg)
{
u8 *pbuf;
static u8 msg_num;
OS_ERR err;
pbuf = mymalloc(SRAMIN,10); //申请10个字节
if(pbuf) //申请内存成功
{
msg_num++;
sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
//发送消息
OSQPost((OS_Q* )&DATA_Msg,
(void* )pbuf,
(OS_MSG_SIZE)10,
(OS_OPT )OS_OPT_POST_FIFO,
(OS_ERR* )&err);
if(err != OS_ERR_NONE) //消息队列已满!
{
myfree(SRAMIN,pbuf); //释放内存
OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
tmr1sta = !tmr1sta;
LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
}
}
}

为何需要 释放内存呀?去掉后,程序也运行正常!

myfree(SRAMIN,pbuf); //释放内存

最佳答案

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

那是因为你的内存池没被用光 等你把内存池管理的内存全部申请光,你就知道正常不正常了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

70

主题

6684

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12613
金钱
12613
注册时间
2012-11-26
在线时间
3701 小时
发表于 2015-7-23 16:25:04 | 显示全部楼层
那是因为你的内存池没被用光

等你把内存池管理的内存全部申请光,你就知道正常不正常了
学无止境
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-7-23 16:25:04 | 显示全部楼层
额,大哥啊,谁告诉你内存申请和释放必须在一个任务中成对出现的!我就不能在任务1中malloc(),在任务2中free()吗?
你看到的定时器回调函数tmr1_callback中一直在申请内存(只有当发送失败的时候才释放内存),函数msgdis_task()却只有释放内存,把这两个函数结合起来看不就对上了!tmr1_callback()函数里面调用OSQPost()发送消息之前肯定要malloc一段内存,msgdis_task()处理掉消息 队列中的消息以后就可以释放掉内存了。
开往春天的手扶拖拉机
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 16:46:09 | 显示全部楼层
说错了,是另一个函数:
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 16:46:20 | 显示全部楼层
//显示消息队列中的消息
void msgdis_task(void *p_arg)
{
u8 *p;
OS_MSG_SIZE size;
OS_ERR err; 
while(1)
{
//请求消息
p=OSQPend((OS_Q* )&DATA_Msg,   
  (OS_TICK )0,
                  (OS_OPT )OS_OPT_PEND_BLOCKING,
                  (OS_MSG_SIZE* )&size,
                  (CPU_TS* )0,
                  (OS_ERR* )&err);
LCD_ShowString(5,270,100,16,16,p);
myfree(SRAMIN,p); //释放内存
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 16:47:06 | 显示全部楼层
// myfree(SRAMIN,p); //释放内存
注释掉,也工作正常。关键是,不知为何需要释放内存。
回复

使用道具 举报

70

主题

6684

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12613
金钱
12613
注册时间
2012-11-26
在线时间
3701 小时
发表于 2015-7-23 16:51:59 | 显示全部楼层
回复【5楼】zydwh:
---------------------------------
那你应改好好百度内存管理的原理
学无止境
回复

使用道具 举报

70

主题

6684

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12613
金钱
12613
注册时间
2012-11-26
在线时间
3701 小时
发表于 2015-7-23 16:52:17 | 显示全部楼层
回复【5楼】zydwh:
---------------------------------
而不是在那异想天开
学无止境
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 16:53:59 | 显示全部楼层
因为这个函数没有申请内存!只看到释放内存,感觉有点特别!
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:01:56 | 显示全部楼层
//定时器1的回调函数
void tmr1_callback(void *p_tmr,void *p_arg)
{
u8 *pbuf;
static u8 msg_num;
OS_ERR err;
pbuf = mymalloc(SRAMIN,16); //申请16个字节
if(pbuf) //申请内存成功
{
msg_num++;
sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
//发送消息
OSQPost((OS_Q* )&DATA_Msg,
(void* )pbuf,
(OS_MSG_SIZE)16,
(OS_OPT )OS_OPT_POST_FIFO,
(OS_ERR* )&err);
if(err != OS_ERR_NONE) //消息队列已满!
{
myfree(SRAMIN,pbuf); //释放内存
OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err);  //停止定时器1
tmr1sta = !tmr1sta;
LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
}
}
}
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:06:03 | 显示全部楼层
定时器1的回调函数 ,好像也有问题,500mS定时到,就申请1次内存,4个500mS定时到,就申请4次内存。但是,第5次,因为消息队列满了,所以发送消息失败,就关闭定时器。总的来说,申请了5次内存,却只释放1次内存,是否有问题呀?
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:06:50 | 显示全部楼层
我是初学者,请大家指教!
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:15:03 | 显示全部楼层
我明白了,定时器1的回调函数 多申请的内存,在“显示消息队列中的消息”任务中释放了。
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:15:21 | 显示全部楼层
//显示消息队列中的消息 
void msgdis_task(void *p_arg) 

u8 *p; 
OS_MSG_SIZE size; 
OS_ERR err;  
while(1) 

//请求消息 
p=OSQPend((OS_Q*  )&DATA_Msg,    
  (OS_TICK  )0, 
                  (OS_OPT  )OS_OPT_PEND_BLOCKING, 
                  (OS_MSG_SIZE* )&size,
                  (CPU_TS*  )0, 
                  (OS_ERR*  )&err); 
LCD_ShowString(5,270,100,16,16,p); 
myfree(SRAMIN,p); //释放内存 
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s 

}
回复

使用道具 举报

55

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2013-1-18
在线时间
56 小时
 楼主| 发表于 2015-7-23 17:16:24 | 显示全部楼层
myfree(SRAMIN,p); //释放内存
这行程序不能去掉!,它释放的是“定时器1的回调函数”中申请的内存。
回复

使用道具 举报

1

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2015-7-16
在线时间
3 小时
发表于 2015-7-23 17:23:51 | 显示全部楼层
在定时器里每发送一条消息,分配一次内存,然后将其加到消息队列里, 正常读消息队列的时候会释放这一块内存,如此循环,不断地生产和消费有何问题?
如果发送失败,那就不应该由读消息队列来释放内存了,而是在本地错误处理处释放掉内存。
逻辑要搞清楚啊。
回复

使用道具 举报

1

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2015-7-16
在线时间
3 小时
发表于 2015-7-23 17:27:42 | 显示全部楼层
回复【14楼】zydwh:
---------------------------------
再说,频繁地分配和释放内存,造成大量的内存碎片,这个习惯可不太好
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-1 14:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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