Re: [问题] 简单的程式就有 memory leak 了

楼主: HuangJC (吹笛牧童)   2014-04-16 20:12:36
来看看 MFC 怎么实作 CString
MFC 在 CString 也是用一种 ref count 机制
而且 MFC 完全公开 source code,也没扩充保留字
有人还把它给拷了,送到没 MFC 但有 C++ 的地方去用
网络上好像找得到,叫 CxString (至少敝公司有维护一套)
CString F1()
{
CString str = "xxx"; // 产生一个字串, ref = 1
return str; // 使用 RC 的书怎么教的? 书上说 str 在离开堆叠时就消失了,
// 所以要 retain
}
那 CString 怎么做呢?
以下是我理解的看法
(书上不是这样教的,总之 source code 公开,去 trace 一下可以印证我的看法)
它把函式的输出结果也当一个变量
你可以想像有一个变量叫做
CString ret;
所以在 F1() 的最后一行, return str;
其实是执行了 ret = str;
然后外面 caller 端再去接这个 ret
比如 caller 端如果是写
CString str2 = F1();
那这里就等于有 str2 = ret; //这个 ret 是刚刚 F1 函式的传回值
然后 ret 就释放了 (写在 CString 的 destructor, ~CString)
如果没人去接,也就是单纯呼叫 F1()
那 ret 也会先接,然后再释放
总之 ref count 的计算是完美的
然后在 ref count 为 0 时, CString 会把内部物件真的释放掉
这一切,不必 precompiler 特别帮忙,不必扩充 C++
它是由标准 C++ 组成的 MFC 完成的,可以转移到没有 MFC 的 C++ compiler 去
若说有什么缺点.. 有
那就是只有 CString 写这么好用
如果我想自己写一个 class, 就不会自动被赋与这么漂亮的机制,要 coding 一堆东西
这其中包括要去覆写 operator, constructor, destructor 等等
然后还有很烦的,比如 operator + 这个 function, 和 const operator + 是不一样的
(就是多了个 const 而已啊..)
要各别覆写,即使内部的 code 其实是一模一样
operator = 和 constructor 可能是不一样的
差异在 ref count 的计算方式
也就是说,想打造一个自己的 class 和 CString 一样好用,要写很多 code
比较简单的方法是 template,不过我和它不熟
听说用 template 可以很快的产生自己的 auto ref count style class.....
在看到 Obj C 的 ARC 时,我以为它是完美的把这套搬进 Compiler
所以我就这么写
- (NSString*)F1
{
NSString* str = @"xxx";
return str;
}
外面 caller 端是
NSString* str2 = [self F1];
以上对 ref 的讨论会一模一样吗? 也就是函式执行结束时,等于有一个中介变量 ret
如果有这种东西,那其实是用不到 autorelease 才对
因为 compiler 帮我们加了 retain & release
return str; //这里要往外传,所以加一个 retain
[self F1]; //这里是 caller 端的角度,已经传出来了,所以加一个 release
NString* str2 = [self F1]; // 这种有 str2 来接,所以会先帮 str2 加一个 retain,
再帮函式的传回值加一个 release, 两个刚好对消, ref count 不变
如果一切像我想的这么完美,那应该用不到 autorelease
我是这么希望的啦
作者: uranusjr (←這人是超級笨蛋)   2014-04-16 21:15:00
安安, 请问知道什么叫 stack allocation 吗?
作者: timTan (用口头禅区分年记)   2014-04-16 22:19:00
CString 不做 Reference Counting
作者: Blueshiva (龙野南云)   2014-04-17 01:05:00
1.早就叫你不要老是不管ObjC怎么做,老是拿其他东西来"以为"硬套 2.@"ooxx"这种NSString是特例,拿这来看看不懂的
作者: atst2 (atst2)   2014-04-17 01:36:00
rc是一种ownership policy, 编译器只管你有没有符合rc规范,不会去猜测你的程式为什么会留着物件不用.另外,要用Instrument就弄清楚工具真正的用法及意义,不要自己单看图表就猜测。以你附的图来说,内存升高又降低,就代表有用到也有释放, Allocation保持一定的内存是原本程式跑起来就需要的,与Leak完全无关。rc这东西在c++也有,去看看STL smart_ptr是怎么回事,去读一下Modern C++ Design(C++设计新思维), Boost, Google的资料也很多...
作者: Blueshiva (龙野南云)   2014-04-17 02:41:00
基本上,如果你自己都已经能找到高见龙的文章来看,那应该就是个会用Google的人,看你能举那么多MFC的东西,应该不会是个程式新手。那为什么会搞成现在这种局面呢?就是"倚老卖老"这四个字造成的,老是以为能拿以前对事物的理解来硬套,然后自己觉得怪怪的,就开始用些更旁门左道的方法来硬干。总归一句,就是根基不稳,然后照你这种个性,我觉得网络上这种一篇一篇的文章给你看了大概也不会有帮助。要我给建议的话,你还是放下无谓的坚持,买本书来看吧。
作者: abcdefghi   2014-04-17 04:23:00
Apple一直在持续改善ObjC, 从语言本身到compiler, 所以有些资讯比较混乱, 真的要深入看, 还是得仔细看官方的技术文件, 再配上其他人的解说, stackoverflow是最好的地方, 不过keyword可能要花点心思.
楼主: HuangJC (吹笛牧童)   2014-04-17 04:27:00
的确... 其实我有时是从两三个互相对立的答案中挑一个就好像这次,有人说'会马上释放',也有人说'不会'我觉得大家贡献自己想法来讨论很好啊奇怪的是我提 MFC 来对照,突然被说'别提以前的经验了'那 ref counting 我读的书,就只有简短几句话"它是 precompiler 自动帮你插入 retain/release"所以我拿 MFC 下学到它何时加一,何时减一,不也是个讨论的起点..我一个同事说:看书太慢,google 比较快主管说:别上网问了,我不信会写的人会在网络上玩
作者: Blueshiva (龙野南云)   2014-04-17 08:16:00
1. 没人说你不能用以前的经验来理解现在的东西,但是注意,是"理解",不是"硬套"。其他地方的经验只是"辅助",而不是像你现在这样"MFC是怎样,ObjC就应该是怎样"2.Google是针对"遇到特定问题"的时候会比较快,但是现在看来,你,或者你们整个team,都不是能够触类旁通,也都没有基础,这样用Google硬干,只是连关键字都不知道怎么下而已。整串下来,也不止我一个跟你讲了,不打基础,那就去找个懂的人加入你们team。你主管猪头觉得东西都一样要你们只学过英文却连あいうえお都搞不清楚的去翻译阪上之云,不代表你就只能把每段话丢到Google翻译剪下贴上交差了事 (当然如果你本来就是这种个性...那就算了)3.会写的人不会在网络上玩?自己google一下zonble、高见龙、xdite,看他们够不够格称得上"会写",再看看他们有没有在网络上"玩"4.找书?没看置底文?5.最后回应一下为什么书都在教没有ARC的版本,因为ARC就只是自动加入retain/release,所以如果你真的要管好内存,了解没有ARC的时候是怎么运作的还是有相当大的帮助或者这样讲吧,把手动管理学起来,转用ARC只是一篇简单教学的事
作者: howdiun (Howdiun)   2014-04-17 11:22:00
instruments里面可以看各物件占用的内存内存吃太多,应该找出吃内存的物件加一减一那是知识,不是拿来实务用的,不知道也可以写

Links booklink

Contact Us: admin [ a t ] ucptt.com