一个小问题引发的论证思考

简介:

    今天,有一个朋友,问了俺一个莫名其妙的问题,问的俺是一愣一愣的,搞了半天愣是没搞明白。他提问的原话是:

一文件流没有创建,怎么判断呢

这个问题还真把我问倒了,我压根就没明白这是个啥意思,后来他说了半天之后,我还是没明白是啥,最后他索性给了一个让我郁闷了半天的代码。如下:

复制代码

  
  
var
Stream : TMemoryStream;
aSkinName : Pchar;
vStrings : TStrings;
begin
inherited ;
vHandle :
= LoadLibrary(Pchar(Gv_SkinFile)); // 动态载入DLL,并返回其句柄
// Stream : = TMemoryStream.Create;
try
if vHandle <> 0 then //
begin
@GetSkin:
= GetProcAddress(vHandle, ' GetSkin ' );
end ;
if not (@GetSkin = nil ) then
begin
Stream :
= TMemoryStream.Create;
aSkinName :
= pchar(Gv_SkinName);
GetSkin(aSkinName,Stream);
with Unit_CommonDm.CommonDm.SkinData do
begin
LoadFromStream(stream);
if not Active then Active : = true;
end ;
end else
begin
// RaiseLastWin32Error;
end ;
finally

FreeLibrary(vHandle);
// 调用完毕收回DLL占用的资源
stream :
= nil ;
if stream = nil then
stream.free;

end ;
复制代码
然后反复强调了最后finally中的一段代码

stream := nil ;
if stream = nil then
stream.free;
看到这个代码,我还真是郁闷了!后来才明白,原来他是想知道Stream到底有没有被创建过,如果没创建,那么就是个坏指针,是不用释放的。结果给整出来了这么个东西!
起初,我直接说,这个代码肯定报错,但是他反复强调,绝对不错,并且让我试试。于是,我试验了一下,哈,果然不报错啊!我在Delphi中测试的代码如下
复制代码

    
    
var
stream: TMemoryStream;
begin
stream :
= TMemoryStream.Create;
stream.Size :
= 234 ;
stream :
= nil ;
if stream = nil then
stream.Free;
end ;
复制代码

这样写,居然不会出错哦!那么这个创建的TMemoryStream到底释放了没有呢?想都不用想,那是肯定没释放的,也就是说有内存泄露,不信的可以用FastMM查看看。至于为

啥出错,我们需要去看TObject的Destroy的代码,这个在Delphi中式没有实现的,我们在调试过程中打开Delphi的CPU调试窗口查看一下汇编代码

1
2
3
4
5
6
7
8
9
10
<pre class ="brush:delphi">TObject . Free:
00403A00 85C0             test eax,eax //这里检查了释放的指针是否为nil
00403A02 7407              jz $00403a0b //如果为nil向后跳7字节,也就是直接跳到ret
00403A04 B201             mov dl, $01
00403A06 8B08             mov ecx,[eax]
00403A08 FF51FC           call dword ptr [ecx- $04 ]
00403A0B C3               ret
 
</pre>
通过这个反汇编,我们就能明白为啥无论一个对象是否为 nil 都会执行了,主要的就是在释放的时候会先判断一下自身是否为空,不为空的时候才会执行释放操作<br data-filtered="filtered"><br data-filtered="filtered">所以,建议大家在这种情况下,先将以后要判断的对象初始化为 nil ,如果不初始化的话,系统分配给对象变量一个不为 nil 的坏指针,那样后面的判断就失效了,我想我朋友估计<br data-filtered="filtered">也是忽略了这一点吧!<br data-filtered="filtered">



本文转自 不得闲 博客园博客,原文链接: http://www.cnblogs.com/DxSoft/archive/2010/05/17/1737116.html ,如需转载请自行联系原作者

相关文章
|
6月前
|
Devops 测试技术 持续交付
软件测试中的敏捷实践:从理论到应用
在软件开发领域,敏捷方法论的兴起已经彻底改变了项目的开发和测试流程。本文将深入探讨如何在软件测试中实施敏捷实践,以及这些实践如何提高产品质量和团队效率。通过引用最新的行业报告、科学研究和统计数据,文章旨在为读者提供一套清晰的指导框架,帮助他们在软件测试过程中实现敏捷性。
91 0
清楚命题的重要性
什么是命题,在现代哲学、数学、逻辑学,命题是指一个判断(陈述)的语句,这个概念是可以被定义并观察的现象。命题不是判断(陈述)本身,而是是所表达的语义。当相同判断(陈述)具有相同语义的时候,他们表达相同的命题。意思就是说:比如上级给你安排一件事情或者是指派任务让你去完成它,成功与否就是自己是否清楚命题
80 0
|
索引
完全依赖基本论证,牛津大学26岁博士生利用业余时间证明素数猜想
完全依赖基本论证,牛津大学26岁博士生利用业余时间证明素数猜想
|
算法
陶哲轩攻克60年几何学难题!发现「周期性密铺猜想」在高维空间反例
陶哲轩攻克60年几何学难题!发现「周期性密铺猜想」在高维空间反例
181 0
不应被忽视的“领域愿景陈述”
**摘要**: Domain Vision Statement(领域愿景陈述,以下简称DVS)是《领域驱动设计》一书的一种模式。在中台上下文下,DVS具有重要的意义。每个中台领域都应该创建自己的明确的DVS、达成共识,并且在认知发生更新时及时演进。 ## 为什么DVS是重要的 我们先来看一个场景。 >行业PD正在和3个领域的平台PD们在讨论一个业务需求的产品方案。看起来现有的产品能力不足以支撑
240 0
不应被忽视的“领域愿景陈述”
|
前端开发 数据可视化 JavaScript
汤尧:走最难的路,看最好的风景
成长一种修炼,借事修人,从项目中探索成长之路,走最难的路,看最好的风景。
汤尧:走最难的路,看最好的风景
|
开发者
系统思考之正反馈在管理学和经济学上的应用分析
系统思考之正反馈的应用分析 从系统思考的角度说,正反馈通过目标与结果之间的相加来增加输入,从而使结果不断增加。正反馈模型可以用于军事学、管理学和经济学的各种理论分析,此处给出管理学上比尔盖茨的正反馈理论和经济学上索罗斯的反身理论,它们的本质都是正反馈模型。
1338 0