为了账号安全,请及时绑定邮箱和手机立即绑定

C语言栈区变量和返回变量疑问?返回变量在系统内部是怎样的流程?

C语言栈区变量和返回变量疑问?返回变量在系统内部是怎样的流程?

一只名叫tom的猫 2019-04-09 20:24:35
比如程序1:int*getIntArr(){intans[3]={1,2,3};returnans;}intmain(){int*p=getIntArr();for(inti=0;i
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

不同的编译器、不同的平台,实现的方式会有差别。理解这些至少需要一些前置知识:CPURegister(学过汇编的都知道)和Functioncallconvention。
简单地讲,C函数只能返回array的指针。函数返回整型值和地址是使用的EAX寄存器(浮点型使用st0),
由于局部变量数据是分配在栈上,函数返回后,栈会被清掉,原来局部变量指针指向的内存区域的数据就不再有保证了。要实现返回array指针后,仍然读取到原来array的数据,则需要使用malloc。
这东西解释起来还有好多概念,
你需要补的知识是这些:
Callingconvention
通常我们都是使用x86平台,可以直接看这个:x86callingconventions
更新
我了个去,提问者竟然将代码又改成C++,还问返回string结果是怎样?题主你不会是看的谭浩强的C语言被误导了吧?
C中只不过有一个stringliteral,这个stringliteral的数据,是在编译时写到datasection中的,这部分在运行时其实是全局的,函数返回后,这部分数据仍然存在。而普通的array,是直接分配在栈上的。同理,变通的方案,如果你将函数局部变量标记成static,则它在函数返回后仍然存在,返回static变量的指针是work的。
char*return_str(){
char*s="hello";
returns;
}
上面的代码工作OK。因为"hello"是被分配到`.section.rodata`中的(如果只是staticchararray,则是`.section.data`),你也许注意到了rodata,说明这个string是不能被修改的,一修改就真的要上segmentfault提问题了。(标准C禁止修改字符串字面量)
你要补的这方面的知识是这个:Datasegment
如果还要寻根究底,则建议直接去看《ProfessionalAssemblyLanguage—RichardBlum》或《ComputerSystems:AProgrammer'sPerspective》
                            
查看完整回答
反对 回复 2019-04-09
?
绝地无双

TA贡献1946条经验 获得超4个赞

简单地说,从栈返回值时该值会被复制,不管它是整数、浮点数、字符、结构体还是指针。返回数组时,实际上返回的是数组的首地址(即一个指针)。
当返回的实际是一个指针时,这里的意思是说这个地址被返回了。如果它指向堆上的内存还好,你没主动释放那片内存就没问题。如果它指向栈上的内存(如你的程序一),那么在返回之后这个值就没有意义了(你只能知道曾经有那么一个数据在那片内存出现过)。
至于具体实现参考@Jex的答案。
提问者竟然更新上去了一段C++代码……
声明:本答案只适用于C。C++本人不会亦从未试图作答。
                            
查看完整回答
反对 回复 2019-04-09
  • 2 回答
  • 0 关注
  • 326 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信