CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

一个局部变量分配的问题

楼主ducktail()2005-08-04 17:59:16 在 C/C++ / C++ 语言 提问

#   include   <iostream>  
  using   namespace   std;  
   
  int   func1()  
  {  
          int   n   =   12345;  
          return   n;  
  }  
   
  int   func2()  
  {  
          int   m;  
          return   m;  
  }  
   
   
  int   main()  
  {  
          func1();  
           
          cout   <<   func2()   <<   endl;  
           
          int   (   *g1   )(   )   =   func1;  
          int   (   *g2   )(   )   =   func2;  
           
          cout   <<   "The   address   of   func1():"   <<   &g1   <<   endl;    
                    //   prinf   the   address   of   func1()  
          cout   <<   "The   address   of   func2():"   <<   &g2   <<   endl;  
          system(   "pause"   );  
  }  
   
  在dev-c++下输出如下:  
  12345  
  The   address   of   func1():0x22ff74  
  The   address   of   func2():0x22ff70  
  Press   any   key   to   continue   .   .   .  
   
  问题是:函数func1()和func2()的结构相同,但是它们分配的地址不一样,m和n分配的地址怎么会一样呢? 问题点数:20、回复次数:14Top

1 楼XBox360(菜)(鸟)回复于 2005-08-04 18:48:18 得分 0

的确很神奇  
  mark一个Top

2 楼hafent(大海扬波)回复于 2005-08-04 18:50:05 得分 0

我在VC6下面试了,第一个输出是-858993460Top

3 楼sankt(宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒.)回复于 2005-08-04 18:59:20 得分 0

猜想:    
  编译器的原因,它把两个变量优化成一个了.Top

4 楼LoveYouJustOneDay(哈哈)回复于 2005-08-04 19:06:22 得分 3

m和n都是栈里分配的  
  栈的数据没有被破坏当然是这样的了Top

5 楼snowbirdfly(专心搞好嵌入式~~~)回复于 2005-08-04 21:18:23 得分 2

VC6下:-858993460  
  The   address   of   func1():0012FF7C  
  The   address   of   func2():0012FF78  
  函数入口地址是应该不同啊!Top

6 楼qhfu(改个名字)回复于 2005-08-04 21:39:53 得分 0

我也觉得是编译器的原因!Top

7 楼lxk_cool()回复于 2005-08-04 22:55:26 得分 0

不懂,学习一下Top

8 楼mayflowers(黯然神伤)回复于 2005-08-04 23:08:35 得分 3

...先多看看书吧,关于函数调用,关于栈,关于局部变量初始化。  
   
  只说一句:    
  cout   <<   "The   address   of   func1():"   <<   &g1   <<   endl;    
  打印的是g1的地址,不是func1的入口地址。  
  要打印可以用:  
  cout   <<   g1   <<   endl;  
  或  
  cout   <<   func1   <<   endl。Top

9 楼zenny_chen(ACE Intercessor)回复于 2005-08-04 23:18:21 得分 2

这可能是dev-C++的编译器对函数中的局部变量做了优化分配。因为当func1调用结束后,m就会被释放。这样  
  m和n居于同一个地址并不会有影像。你可以试试将func2嵌入到func1中,结果会如何。  
   
  另外,你下面输出的是g1和g2它们自己所处的地址而不是它们所指函数的地址。要看它们所指函数的地址应该将&去掉。  
   
  Top

10 楼jiajun2001(Jagen(嘉俊))回复于 2005-08-04 23:31:43 得分 10

我来帮你解答!  
  这是由于局部变量的存储位置是堆栈,与具体的函数所在的地址没有关系。  
  我们知道,i386体系的堆栈都是向下增长的。那么在C/C++语言中,函数的参数以及局部变量都存储在这个堆栈中的。一个应用程序启动时,操作系统就会为他分配一个堆栈地址空间,由esp寄存器维护。如果创建一个现程后,操作系统还会为新的显程分配堆栈地址空间,也是由esp寄存器维护。在进行任务切换时,修改esp寄存器就可以。不过这不是我们要讨论的主要问题,仅作为一个开头,让大家对堆栈有一个印象。  
  向楼主提出的这个问题,很有特点。他的两个函数型除名称外,其他都一模一样。那么,它们在的内部实现也就是差不多一模一样了。它们产生的对应的汇编代码就差不多是下面这样:  
  func1:  
  push   ebp  
  sub   esp,   4   ->这里分配局部变量n  
  mov   ebp,   esp  
  mov   [ebp+4],123456   ->为n附初值,记住堆栈是向下增长的  
  mov   eax,   [ebp+4]         ->返回值放在eax中传回  
  add   esp,   4                     ->恢复堆栈  
  pop   ebp  
  ret  
   
  func2:  
  push   ebp  
  sub   esp,   4  
  mov   eax,   [ebp+4]  
  add   esp,   4  
  pop   ebp  
  ret  
   
  那么调用它们的汇编代码基本如下:  
  call   func1  
  call   func2  
   
  由于func1已经将12345移到堆栈所使用的内存中了,在两次函数调用期间也没有对堆栈进行过操作,而局部变量m和n恰好在堆栈的同一位置,因此,m和n所分配的地址相同,内容也相同,这就是为什么没有初始化的局部变量值不确定的原因。  
   
  而对于VC而言,他们在debug模式下,都会把未初始化的变量自动初始化为0xcccccccc,他们实际上是8个汇编代码int   3的机器码,VC这样做主要是为了调试。  
  因此func2的汇编代码在VC下可能就是:  
  func2:  
  push   ebp  
  sub   esp,   4  
  mov   [ebp+4],   0xcccccccc  
  mov   eax,   [ebp+4]  
  add   esp,   4  
  pop   ebp  
  ret  
  这样,程序的输出结果肯定就变了,如果你使用Release方式编译的话,肯定得到的是楼主的结果。  
  Dev-cpp默认的时候就是Release编译。  
  这不属于编译器的优化起的作用。  
  Top

11 楼waynahu(FIRE_BIRD-->涅磐)回复于 2005-08-05 08:54:00 得分 0

函数func1()和func2()的结构相同,但是它们分配的地址不一样,m和n分配的地址怎么会一样呢?  
  ???????????????  
  什么“m和n分配的地址怎么会一样呢”,不懂。请问你从程序的哪个地方发现的啊?Top

12 楼jiajun2001(Jagen(嘉俊))回复于 2005-08-05 09:21:02 得分 0

m和n分配的地址确实是相同的,看我上面的解释Top

13 楼XBox360(菜)(鸟)回复于 2005-08-05 10:28:01 得分 0

但是在VC中结果不一样  
  -858993460Top

14 楼jiajun2001(Jagen(嘉俊))回复于 2005-08-05 21:12:59 得分 0

我上面也解释了,你把0xcccccccc转变成10进制,你看看是不是-858993460!  
  你干脆把这两个变量的地址输出出来,你看看,肯定是一样的!Top

相关问题

  • 关于局部变量!!!
  • 局部变量与栈
  • delphi里没静态局部变量?
  • 关于函数返回局部变量
  • 局部变量作返回值
  • 局部变量重名问题
  • 局部变量传指针问题
  • 你理解了吗?普通局部变量、线程局部变量的区别,欢迎讨论
  • 静态局部变量的问题,我倾听您的教诲!
  • 线程的局部变量为什么会被修改掉???

关键词

  • 汇编
  • 代码
  • 局部变量
  • 分配
  • 堆栈
  • func
  • 初始化
  • 地址
  • ebp+4
  • 汇编代码

得分解答快速导航

  • 帖主:ducktail
  • LoveYouJustOneDay
  • snowbirdfly
  • mayflowers
  • zenny_chen
  • jiajun2001

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo