作者b0920075 (Void)
看板C_and_CPP
标题Re: [问题] function 里的变数 存活时间
时间Fri Dec 22 15:35:57 2017
※ 引述《gamed (Maiko)》之铭言:
: 我朋友最近去面试
: 其中有一个主管考一题
: char *fun()
: {
: char str[] = {"Hello"};
: return str;
: }
: void main()
: {
: char *p = NULL;
: p = fun();
: printf("%s\n", p);
: }
: 问结果如何
: 主管给的回答是这样可以把指标传出来
指标传出来我想是没问题的,这样就单纯把指到这空间的地址回传出来而已,除非编
译器很好心帮你加工过
: 所以可以印出结果
是可以印出东西,但东西是不是对的比较重要XDD
: 我的观念是 function 的变数只要离开回圈
: 都会被归还OS(除了malloc)
: 我的想法对吗?
OS应该是程式结束後才会接手吧?离开function,东西还是会留在那,但下一个用到
该空间的function如果有对该空间写值就会被盖过去,你一点办法都没有,换句话说
无法保证资料的正确性
: 我在公司电脑(ubuntu)
: 的确可以印出字串 囧
那就只是刚好没有function对该空间写值
: 但家里的电脑(ubuntu)却印出乱码
info leak !
: 我有印出指标位址
: 的确可以把位址传出来
我自己用gcc 5.4测试,看起来编译器会在fun()结尾的时候把rax归0,不让指向区域
变数的指标回传
: 我後来想想
: 在公司电脑可以顺利印出字串
: 是运气好 刚好那段位址的内容没被覆盖??
: 如果想法有错误
: 请各位前辈能多给指导
: 谢谢
就是运气好别怀疑,後续的printf里面用的变数也是用stack上的空间存放,没被盖掉
真的就是运气好
这种写法很糟,很容易有安全性问题,就像你在家试的时候印出的乱码很可能就是泄
漏出敏感地址,让系统保护形同虚设
大概是这样子吧,不知道有没有说错QQ
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.117.178.137
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1513928161.A.0DB.html
1F:→ galic: 先不论对错 主管这样考就是预期你面试的时候 讲出这篇8成的 12/22 17:19
2F:→ galic: 内容... 可见这种面试多没有成效 12/22 17:20
3F:→ galic: 我不太能理解为何面试要搞的像震撼教育 然後逼的来面试的人 12/22 17:21
4F:→ galic: 除了被洗脸之外 还要回家上网google 上ptt问解答 12/22 17:21
原先我看到原文以为主管在考不要回传区域阵列地址这种观念,但是看描述怎麽觉得主管才是搞不清楚的XDDD
5F:推 Hazukashiine: 我倒是很喜欢这种开放式问答的题目 XD 12/22 17:23
6F:推 mmmmei: 那请问一下该怎麽写才不会有memory leak 又可以在函数外pr 12/22 17:38
7F:→ mmmmei: int? 12/22 17:38
如楼下所说,建议是malloc一个空间,把你要写的东西放在malloc出来的空间里面,因为空间在heap内,所以不
会因为离开function而丧失控制权,malloc出来的空间会丧失控制权就是在你free掉空间的时候,当然如果free完
又去读写空间,也会造成安全性问题:info leak和use after free
至於global array的话,如果宣告即给初始值会放在data,没有的话放在bss,不管放哪个没有控制权丧失的问题
但是当你不用的话你也不能回收再利用,相较malloc可以把不用的空间free掉,这种使用方式比较......不节约?
8F:推 Hazukashiine: 1. global char[] 2. heap allocation (preferred) 12/22 17:45
9F:→ loveflames: static local 12/22 17:49
※ 编辑: b0920075 (140.117.178.137), 12/22/2017 18:06:58
10F:推 boss0405: 这麽基本的问题如果还不懂很难想像写出来的code会多可怕 12/22 18:12
11F:→ boss0405: 但可怕的是原PO的主管似乎认为可以这样用 12/22 18:12
12F:→ boss0405: 不过我也曾经听过有某公司软体主管说extern global 12/22 18:14
13F:→ boss0405: variable不要放在header file,然後说出一个错误的原因 12/22 18:14
14F:推 CoNsTaR: 如果面试遇到楼上讲的那样的主管该怎麽办啊 orz 12/23 00:37
15F:→ Schottky: 当然是块陶,面试官是你以後的同事,有这种雷同事哪行 12/23 02:31
16F:推 mmmmei: 那在c++ 就是char *ptr = new char[5] 这样吗? 12/23 14:48
17F:推 steve1012: 在 c++应该会用 string XD 没事不会砸自己的脚 12/23 15:04
18F:推 mmmmei: 哎呀!单纯疑问观念 现实有STL可以用当然用 12/23 15:35
19F:→ loveflames: 最好加上{} 12/23 17:01
20F:→ NoManInCar: 有个疑问 c++在function new出来的 应该也不能传出来 12/24 09:46
21F:→ NoManInCar: 吧? 12/24 09:46
22F:→ NoManInCar: 我好像弄错了 这边我在想想 12/24 09:47
23F:→ uranusjr: new 和 malloc 在根本上是一样的概念 12/24 10:01
24F:→ loveflames: 两个实作或许一样,不过new是free store,malloc是hea 12/24 10:26
25F:→ loveflames: p 12/24 10:26
26F:推 hakman: 我想要知道为什麽 extern global variable 不要放在header 12/24 23:08
27F:→ hakman: file ,有人可以说明一下吗? 感恩 12/24 23:08
28F:推 boss0405: 楼上,因为那主管搞错观念了,所以这结论也是错的XD 12/24 23:32
29F:推 Killercat: new传出来不是不行 只是是不好的写法 12/28 14:58
30F:→ Killercat: 通常来讲new/delete要在同一个scope做,不能A()new了 12/28 14:58
31F:→ Killercat: 传出来要使用者自己delete 12/28 14:58
32F:→ Killercat: 不然就得wrap一下 比方说C* Alloc() 跟 Release(C*) 12/28 14:59
33F:→ Killercat: C*再用typedef包一下或者拿个warpper class处理一下 12/28 14:59
34F:→ Killercat: btw, shared_ptr好方便的啊..大家都忘了很多原则了XD 12/28 15:00
35F:→ uranusjr: 还是 Rust 大法好, 加上 lifetime 不会有这个问题了 (欸 12/29 03:23