打印

操作系统切忌用指针访问任务栈上的空间

[复制链接]
1319|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sioca|  楼主 | 2014-6-9 10:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sioca 于 2014-6-9 18:07 编辑

一本STM32和FREERTOS的书籍中写到:
“切忌用指针访问任务站上分配的空间。因为当栈帧发生改变后,栈上的指针将不再有效。”

请问这句话怎么理解,任何局部变量不都是栈上面的么。如下语句执行期间进行任务切换也有风险?
【in task】:

while(1){
    int i, *p;
    p = &i;
    p++;
    p++;
}

相关帖子

沙发
ayb_ice| | 2014-6-9 11:17 | 只看该作者
没有这说法

此处指针最后指向了非法空间,但没有改变空间的值也是可以的

不能在多任务访问是真的(此处是局部变量没有问题)

使用特权

评论回复
板凳
aozima| | 2014-6-9 11:21 | 只看该作者
楼主位的代码的问题并不在于i是在栈中,即使不在栈中依然有问题。
比如
int i;

foo()
{
    int *p;
    p = &i;
    p++;
    p++;
}
下面这个代码才是因为“当栈帧发生改变后,栈上的指针将不再有效”
int *foo()
{
    int i, *p;
    p = &i;
   
    return p;
}

使用特权

评论回复
地板
sioca|  楼主 | 2014-6-9 13:33 | 只看该作者
aozima 发表于 2014-6-9 11:21
楼主位的代码的问题并不在于i是在栈中,即使不在栈中依然有问题。
比如下面这个代码才是因为“当栈帧发生改 ...

谢谢!
第二个程序会有问题吗?
i 和 p的生命周期都是一样的吧,p有效时,i的地址也不会变动吧。

此外,您给的程序一和程序二,i的地址空间应该都在栈空间里吧。

使用特权

评论回复
5
aozima| | 2014-6-9 14:50 | 只看该作者
sioca 发表于 2014-6-9 13:33
谢谢!
第二个程序会有问题吗?
i 和 p的生命周期都是一样的吧,p有效时,i的地址也不会变动吧。

我的程序1,i是全局变量,问题叫“缓冲区溢出”或“野指针”。

问题2参考:刻舟求剑。

使用特权

评论回复
6
sioca|  楼主 | 2014-6-9 18:04 | 只看该作者
本帖最后由 sioca 于 2014-6-9 18:07 编辑
aozima 发表于 2014-6-9 14:50
我的程序1,i是全局变量,问题叫“缓冲区溢出”或“野指针”。

问题2参考:刻舟求剑。 ...

再次感谢!
不过小弟还是没看出问题出现在什么地方。

下面是我对程序2的理解:

若程序被调用一次,堆栈顶端划分申请i和p两个堆栈,其中p指向i,函数执行中若出现进程切换,则操作系统负责现场保存(栈指针保存),再切换回之后,i p所在的堆栈和堆栈地址并没有发生变化。因此只要i生命期不结束(不出栈),则p永远指向i在栈中的地址,如果i生命期满地址无效(出栈),由于p和i申请的位置一样,生命周期也一样,因此p指针肯定也无效了,指针同时消亡,此时也不会出现问题。

即:每个foo函数的调用实体在其生命周期内都对应有一个进程,即有一个固定的栈,即固定的地址, 进程切换时不存在i和p绝对地址变换的场景,即i不会从一个内存地址挪到另外一个地址,同时p还保有i的旧地址。

使用特权

评论回复
7
sioca|  楼主 | 2014-6-9 18:09 | 只看该作者
如果p是全局变量,那么我能看出来问题,因为函数中的i生命周期比p要短,而且多次调用时没有N个p与N个i互相对应。会出现一个p对应N个i的错误情况。

使用特权

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

本版积分规则

个人签名:1

122

主题

419

帖子

1

粉丝