打印
[8/16-bit MCU]

堆栈爆了!把一个函数分为2个就过了,好奇怪

[复制链接]
2058|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
forthlab|  楼主 | 2015-10-8 16:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 forthlab 于 2015-10-8 16:16 编辑

使用AC32的CPU,CW6.3
程序里面有很多三角运算,都是double类型的,修改堆栈大小,2K内存1600是堆栈,不能再大了
程序都是简单的顺序运算,调用sin(),cos(),按常理一个三角公式算完会占用较多的内存,但运算结果出来后堆栈要释放,再计算下一个公式,但在单步执行的时候发现堆栈指针没有释放,占用越来越多,sp越来越小,终于昨天SP成了个位数,程序爆了!
把局部变量改为全局变量也没有效果;
修改CW的“智能游标”,调节代码大小、执行速度也没有用;
因为程序不复杂,于是将函数分为2个子程序,最大堆栈占用就只有一半了,单步执行发现,第一个子程序执行时,堆栈也是逐步侵吞,子程序执行完了,推迟子程序,堆栈被释放;在调用第二个子程序,搞定。
我现在不理解的是为何堆栈没有释放?
简单描述一下程序:

原来的程序:
fun(a,b,c)
{
double A,B,C;
A= sin(a)/cos(b);
B= sin(c)+cos(A+b);
........
C = sin(a+b)/cos(A+B);
}
这个程序很占用内存,于是分为2个子程序:
double A;
fun1(a,b,c)
{
double B,C;
A= sin(a)/cos(b);
...........
}

fun2(a,b,c)
{
double B,C;
B=sin(a)/cos(b);
........
B= sin(c)+cos(A+b);
........
C = sin(a+b)/cos(A+B);
}

这么解决问题的,好奇怪







相关帖子

沙发
FSL_TICS_Jeremy| | 2015-10-8 17:12 | 只看该作者
试试操作系统中用于内存管理的思想,人为的释放掉堆栈空间,看能不能避免同样的问题

使用特权

评论回复
板凳
quray1985| | 2015-10-8 21:26 | 只看该作者
是不是算完一个立马就释放内存啊

使用特权

评论回复
地板
forthlab|  楼主 | 2015-10-9 15:00 | 只看该作者
quray1985 发表于 2015-10-8 21:26
是不是算完一个立马就释放内存啊

我也觉得算完一个公式就应该释放计算过程中用到的内存。
这应该是C编译器做的工作吧。

使用特权

评论回复
5
forthlab|  楼主 | 2015-10-9 15:03 | 只看该作者
FSL_TICS_Jeremy 发表于 2015-10-8 17:12
试试操作系统中用于内存管理的思想,人为的释放掉堆栈空间,看能不能避免同样的问题 ...

这个问题我觉得不应该发生
内存管理是C编译器的事情
Codewarrior一直用的很好
为何CW这次会出这么弱智的问题?
感觉FSL不应该啊

使用特权

评论回复
6
forthlab|  楼主 | 2015-10-9 15:05 | 只看该作者
FSL_TICS_Jeremy 发表于 2015-10-8 17:12
试试操作系统中用于内存管理的思想,人为的释放掉堆栈空间,看能不能避免同样的问题 ...

如何释放?

使用特权

评论回复
7
FSL_TICS_Jeremy| | 2015-10-9 16:30 | 只看该作者
forthlab 发表于 2015-10-9 15:03
这个问题我觉得不应该发生
内存管理是C编译器的事情
Codewarrior一直用的很好

从你的表述来讲,在一个函数执行函数功能,编译器没有对堆栈进行释放而导致空间占用过多,而变成两个后,前面一个在调用后一个函数后,会就被释放掉。
从编译器角度讲,这是由它的工作机制决定的,堆栈的调用与你程序运算复杂程度没有绝对的关系,与你调用的变量数量有关,如果都是集中在同一个函数中,是会有占用过多堆栈空间的可能

使用特权

评论回复
8
forthlab|  楼主 | 2015-10-10 00:19 | 只看该作者
FSL_TICS_Jeremy 发表于 2015-10-9 16:30
从你的表述来讲,在一个函数执行函数功能,编译器没有对堆栈进行释放而导致空间占用过多,而变成两个后, ...

局部变量是有10个左右
但我改为全局变量后,还是没有改变。
似乎无法解释

使用特权

评论回复
9
FSL_TICS_Jeremy| | 2015-10-10 09:05 | 只看该作者
forthlab 发表于 2015-10-10 00:19
局部变量是有10个左右
但我改为全局变量后,还是没有改变。
似乎无法解释 ...

还有跟函数内部反复调用前面得到的变量有关,这些都需要入栈进行保护的

使用特权

评论回复
10
forthlab|  楼主 | 2015-10-10 09:49 | 只看该作者
本帖最后由 forthlab 于 2015-10-10 09:51 编辑
FSL_TICS_Jeremy 发表于 2015-10-10 09:05
还有跟函数内部反复调用前面得到的变量有关,这些都需要入栈进行保护的 ...

如果要用前面的变量,只需要保留变量的结果,不需要把计算过程用到的堆栈也保留啊。

使用特权

评论回复
11
FSL_TICS_Jeremy| | 2015-10-10 10:09 | 只看该作者
推荐你看看这篇分享,增加里面堆栈的操作原理
http://www.51hei.com/bbs/dpj-37256-1.html

使用特权

评论回复
12
forthlab|  楼主 | 2015-10-10 13:28 | 只看该作者
本帖最后由 forthlab 于 2015-10-10 13:44 编辑
FSL_TICS_Jeremy 发表于 2015-10-10 10:09
推荐你看看这篇分享,增加里面堆栈的操作原理
http://www.51hei.com/bbs/dpj-37256-1.html ...

好吧,你要我看我就看看,看过后我承认我表述不准确:准确地说,是栈溢出了!

那么
现在你可以回答我的问题了吧:
1. 为何我的函数调用sin(), cous()的三角函数,栈会溢出?
2。 我把一个函数拆为2个后就不溢出了。

回收用过的栈空间是C编译器的工作,你让我看的**也是这么写的,可是CW却不回收,哪里出问题了?




使用特权

评论回复
13
Luis德华| | 2015-10-10 21:28 | 只看该作者
对啊,试着把内存空间释放了

使用特权

评论回复
14
forthlab|  楼主 | 2015-10-12 21:14 | 只看该作者
Luis德华 发表于 2015-10-10 21:28
对啊,试着把内存空间释放了

如何释放啊?
这个空间不是我申请的,是编译器生成的

使用特权

评论回复
15
forthlab|  楼主 | 2015-11-24 19:37 | 只看该作者
还没有人能解释么?


使用特权

评论回复
16
cowboy2014| | 2015-11-24 19:51 | 只看该作者
自己申请了内存然后自己释放

使用特权

评论回复
17
forthlab|  楼主 | 2015-11-25 08:57 | 只看该作者
cowboy2014 发表于 2015-11-24 19:51
自己申请了内存然后自己释放

我没有申请内存的操作,如何释放?

使用特权

评论回复
18
cowboy2014| | 2015-11-27 08:54 | 只看该作者
你申请内存后用完了一定要释放啊

使用特权

评论回复
19
forthlab|  楼主 | 2015-11-28 23:23 | 只看该作者
cowboy2014 发表于 2015-11-27 08:54
你申请内存后用完了一定要释放啊

我调用函数如sin(),cos(),调用后如何释放内存啊?

使用特权

评论回复
20
Roderman_z| | 2015-11-29 19:59 | 只看该作者
只能换一种思维来解决这个问题了,比如操作系统的内存管理

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

87

主题

749

帖子

5

粉丝