-

- 加为好友
- 发送私信
- 在线聊天
|
| 发表于:2008-10-30 02:02:578楼 得分:0 |
#include <iostream.h> int* gettest() { int a=1; int *b=&a; return b; } void main() { int *x=gettest(); cout < <*x < <endl;//输出结果 是 1 正确 cout < <endl; cout < <endl; cout < <endl; cout < <endl; cout < <*x < <endl;//输出结果错误 } 现在进入 main 假设栈顶是esp=256,在函数调用的时候占用栈8字节. 当前的变量分配最高位为ebp = 288 定义一个变量,位置在ebp-4 int *x;(x的地址为284) 调用的时候esp = 248 (即:256-8) 保存esp 令ebp = 248 esp 的值减去一个数,比如32,也主是说216到248的内存给函数gettest使用. 变量a地址为ebp-4 = 244,值为1 变量b地址为ebp-8 = 240,值为244 (a的地址) 现在程序返回. 栈恢复到 esp = 256 ebp = 288 那么244赋给了main中的变量x endl进栈 esp = 252 x的值进栈: 现在注意,内存地址为244的数据还是1,没有被改写. 于是1进栈 esp = 248 调用cout的operator < <方法 esp 减去八 等于240 实际上在240到248的位置上是ebp的值和,函数的返回地址 于是244内存的数据被破坏.... ................ 这里对cout的operator < <方法依赖于实现. 总之,内存244这个位置的数据一般说来,再次调用函数,就会被破坏. 为了避免,在没有被破坏时,无意访问了这个内存,而让程序员误以为这些数据是可以访问的(呵,当然是可以访问的,这里是说,有没有效的问题),编译器可能在gettest返回时,把使用过的栈上的数据设置为某个特殊的值. 所以,你就是在编译器没有做这个保护的情况下,无意中访问了,巧合... | | |
修改
删除
举报
引用
回复
| |