首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

关于取函数返回值地址的有关问题

2013-07-09 
【求助】关于取函数返回值地址的问题遇到一个问题,请大侠们指点以一个代码为例:#include iostream#include

【求助】关于取函数返回值地址的问题
遇到一个问题,请大侠们指点
以一个代码为例:


#include <iostream>
#include <string.h>
int getName()
{
     int i = 20;
     return i;

int main()
{
     int *p;
     p = &getName();
     return 0;
}


对于基础类型,简单数据返回结果会返回在eax寄存器中,上面的代码会报错
但是如果返回的不是int而是一个对象的话,返回的效果应该是在栈上开一块空间传入到函数中,函数中把对象拷贝到对应空间处,返回返回值的指针在eax寄存器中。

但是如果我像下面这样的

ClassName getVal()
{
    .....
}

int main()
{
    ClassName *name;
    name = &getVal();
    ...
    return 0;
}


会得到一个编译器告警,编译成功,但是这个样子这块栈空间什么时候释放呢?是不是说因为我有一个指针的指向而一直不释放呢?怎么样才能体现他确实释放了呢? 我在name = &getVal();后写了一堆的调用函数的代码,函数的入参都很大,可是不管怎么多调用,最后取出name的值仍然是完好的,很迷茫啊,求解释
[解决办法]
内存在函数调用的表达式结束后就回收了.
回收并不代表内存就不可用了. 内存还在, 只是编译器随时可能把它用于其他用途. 
如果你运气好, 编译刚好还没有把它用作其他的, 你就看不到错误.

[解决办法]
引用:
Quote: 引用:

Quote: 引用:

内存在函数调用的表达式结束后就回收了.
回收并不代表内存就不可用了. 内存还在, 只是编译器随时可能把它用于其他用途. 
如果你运气好, 编译刚好还没有把它用作其他的, 你就看不到错误.


现在我可能比较纠结于的不是这个问题,大数据的返回是在old ebp之前的一段空间里存储返回值的,返回的结果我取地址,在栈里我用什么方式可以确保这块空间被重新分配使用,可以看到效果,这个按照理论来讲确实应该是释放的,但是我怎么能看到呢?我在Linux环境下跑,默认的栈大小应该是10M

不知道我理解的对不对:如果我创建局部变量,是在编译时放在Data段的,跟栈没啥关系,我用同样的函数调用的方式,可是调用的次数虽然很多,但是仍然没有用到这块空间,有什么行之有效的方法可以证明这个理论吗?让其100%复现,比如说一个函数把所有空闲的栈空间置0


函数的局部变量内存是在栈里面的, 不在文件的 Data 段. 但是是在一进入函数的时候就分配了的, 而不是定义变量的时候. 
要让他失败, 可以试试调用其它的函数. 


正解,我给代码解释下
咱先把引用去掉,在c下编译是通不过的

 2 #include <stdio.h>
  3 #include <string.h>
  4 int getName()


  5 {
  6              int i = 20;
  7                   return i;
  8 } 
  9 int main()
 10 {
 11              int *p;
 12                   *p = getName();
 13                        return 0;
 14 }


gcc编译后,反汇编得到的结果

80483b4 <getName>:
119  80483b4:   55                      push   %ebp
120  80483b5:   89 e5                   mov    %esp,%ebp//
121  80483b7:   83 ec 10                sub    $0x10,%esp
122  80483ba:   c7 45 fc 14 00 00 00    movl   $0x14,-0x4(%ebp)
123  80483c1:   8b 45 fc                mov    -0x4(%ebp),%eax//here1
/*很显然here1它把返回值放到了寄存器eax中,然后有主函数中here2存到对应的变量中去。
也就说这个操作执行后,函数getname中局部变量-0x4(%ebp),已经不再重要了,
因为它的值已经转移走了。系统可以用他干别的事情了。而且它是在栈里面的,局部于%ebp
在进入函数的时候push   %ebp保存调用函数地址;mov    %esp,%ebp转向被调用函数栈指针*/
124  80483c4:   c9                      leave
125  80483c5:   c3                      ret
126 
127 080483c6 <main>:
128  80483c6:   55                      push   %ebp
129  80483c7:   89 e5                   mov    %esp,%ebp
130  80483c9:   83 ec 10                sub    $0x10,%esp


131  80483cc:   e8 e3 ff ff ff          call   80483b4 <getName>
132  80483d1:   8b 55 fc                mov    -0x4(%ebp),%edx
133  80483d4:   89 02                   mov    %eax,(%edx)//here2
134  80483d6:   b8 00 00 00 00          mov    $0x0,%eax
135  80483db:   c9                      leave
136  80483dc:   c3                      ret
137  80483dd:   90                      nop
138  80483de:   90                      nop
139  80483df:   90                      nop


热点排行