函数内部临时变量

来源:互联网 发布:为知笔记本地部署 编辑:程序博客网 时间:2024/06/05 16:34
这是我在回复CSDN的C版区一个问临时变量问题的回复内容。以前也看到很多类似的问题,这次写了几句简单的代码,测试后算作一个总结吧!#include <stdio.h>  2 static int num = 10;  3 static int *add = NULL;  4 int get_value()  5 {  6     int temp = num;        //嵌入汇编语言,咱把局部变量的地址取出来,然后在外部使用  7     __asm__ volatile(  8                     "movl %%ebp, %%edx\n\t"  9                     "subl $0x4, %%edx\n\t" 10                     :"=d"(add) 11                     :); 12     return temp; 13 } 14 int main() 15 { 16     int i; 17 18     get_value();//获取结果为10,标志获取临时变量temp地址成功 19     printf("1 old value:%d\n", *add); 20     *add = 30;//我们使用这个临时变量,是可以使用的,得到30 21     printf("new value:%d\n", *add); 22     i = get_value(); 23     printf("return value:%d\n", i);        printf("2 old value:%d\n", *add); //2次调用后,结果又刷回到10 24     return 0; 25 }

下面是gcc 4.6.3编译后并反汇编的结果,主函数就不帖了,无关紧要

 
080483e4 <get_value>:124  80483e4:   55                      push   %ebp125  80483e5:   89 e5                   mov    %esp,%ebp126  80483e7:   83 ec 10                sub    $0x10,%esp127  80483ea:   a1 14 a0 04 08          mov    0x804a014,%eax128  80483ef:   89 45 fc                mov    %eax,-0x4(%ebp)129  80483f2:   89 ea                   mov    %ebp,%edx//这4句是我加的内容,得到%ebp-0x4地址,因为整数占4B(32bit)130  80483f4:   83 ea 04                sub    $0x4,%edx131  80483f7:   89 d0                   mov    %edx,%eax132  80483f9:   a3 20 a0 04 08          mov    %eax,0x804a020133  80483fe:   8b 45 fc                mov    -0x4(%ebp),%eax134  8048401:   c9                      leave135  8048402:   c3                      ret


当然如果嵌入汇编不好理解,你可以直接取地址,像这样
int get_value()  5 {  6     int temp = num; 12     add = &temp; 13     return temp; 14 }


效果是一样的

我这样做并不是鼓励去使用或者引用临时变量,而是要清楚几点:

1. 内存在函数调用的表达式结束后就回收了. 回收并不代表内存就不可用了. 内存还在.这里的回收意思可作为空闲区由系统分配。(比如我在主函数里使用它)

2. 函数的局部变量内存是在栈里面的, 不在文件的Data段.(mov  %esp,%ebp可证明)

3. 临时变量生命期由函数的返回,弹出栈操作回到调用函数,而让用户不再拥有看到局部变量的地址而算作“消亡”。其实这点算作第1点的补充,所以“消亡”要加引号。

4. 记住不要在外使用“消亡”的临时变量,否则,只会造成潜在的bug!

原创粉丝点击