Subject: 第三方代码JCL在D11下出现Exception时内存有漏 [Print This Page]
Author:
niaoge Time: 2007-8-12 11:09 Subject: 第三方代码JCL在D11下出现Exception时内存有漏
第三方代码JCL的JCLDebug.pas,在D11下出现Exception时内存有漏,而且很严重
建议用JCL最新版试试,
我已经用JCL1.100代码编译了cw,没出现编译不通过
有空我测测再看看
Author:
niaoge Time: 2007-8-13 09:40
CnLangUtils.pas
function GetLocaleDataW(ID: LCID; out Flag: DWORD): string;
//加一个 out 不然这里内存有异常,
//其实我也不知道为什么要加out ,兴好昨晚认真看了stanleyxu2005 的贴子http://bbs.cnpack.org/viewthread.php?tid=1712&extra=page%3D1还有点记得
//刚好今天用BoundsChecker测cw,这里出现内存异常,于是就想到昨天的贴子,果然,加了out之后就没有了异常了,stanleyxu2005 大虾一个
function GetLocaleDataA(ID: LCID; out Flag: DWORD): string;
//同上加一个 out
CnWizClasses.pas
// if FIconHandle <> 0 then //加判断也没有用
// DestroyIcon(FIconHandle); //不要这个,IDE自动释放FIconHandle,所以加了DestroyIcon反而找不到地址
上面的改动之前,D11启动后,什么也不动,总内存使用是0.9-1G,改完之后是 0.8G左右,足足快差200M
接贴
CnAlignSizeWizard.pas 内
新建窗体时,BoundsChecker会报地址错误,由是多加以下判断,改完之后正常了
function TCnAlignSizeWizard.UpdateNonVisualComponent(
FormEditor: IOTAFormEditor): Boolean;
var
Component: IOTAComponent;
aWinControl:TWinControl;
aPointer: Pointer;
procedure DoHideNonvisualComponent(WinControl: TWinControl);
var
H: HWND;
aHandle:HWND;
begin
aHandle:=WinControl.Handle;
if aHandle<>0 then //多加判断,有异常
begin
H := GetWindow(aHandle, GW_CHILD);
if H<>0 then //判断
begin
H := GetWindow(H, GW_HWNDLAST);
while H <> 0 do
begin
if HWndIsNonvisualComponent(H) then
if Active and HideNonVisual then
ShowWindow(H, SW_HIDE)
else
ShowWindow(H, SW_SHOW);
H := GetWindow(H, GW_HWNDPREV);
end;
end;
end;
end;
begin
Result := False;
if Assigned(FormEditor) then
begin
Component := FormEditor.GetRootComponent;
if Assigned(Component) and Assigned(Component.GetComponentHandle) and
(TObject(Component.GetComponentHandle) is TWinControl) then
begin
aPointer:=Component.GetComponentHandle;
if aPointer<>nil then //判断
begin
aWinControl:=TWinControl(aPointer);
if Assigned(aWinControl) then //判断
begin
DoHideNonvisualComponent(aWinControl);
Result := True;
end;
end;
end;
end;
end;
经过上面一系列的改动, 使用到现在,cw很正常了,BoundsChecker也没有报错
[ 本帖最后由 niaoge 于 2007-8-13 14:07 编辑 ]
Author:
niaoge Time: 2007-8-13 13:53
上面内容是用BoundsChecker测的,fastMM和AQ没测出来
Author:
Passion Time: 2007-8-13 14:32
加out的,理由不充分吧,参数是个DWORD,不是结构啊?
Author:
niaoge Time: 2007-8-13 15:05
原帖由 Passion 于 2007-8-13 14:32 发表
加out的,理由不充分吧,参数是个DWORD,不是结构啊?
你下载一个BoundsChecker测一下,然后加上Out测一下,会不会dword类型也与string一样,也是一个地址加上引用次数,汇编俺不懂,你能不能用汇遍看看加与不加out 各是什么样子的
Author:
Passion Time: 2007-8-14 19:25
DWORD就是一个简单的4字节值,没有引用计数的说法。GetLocaleDataW这块参考的是VCL中的写法,应该不会有啥问题的,怕是BoundsChecker误报。
CnAlignSizeWizard.pas 中我参考niaoge的意见做了一些修改,希望有空帮我们重新看看有无此等问题。
Author:
Passion Time: 2007-8-14 23:53
CnWizClasses.pas
// if FIconHandle <> 0 then //加判断也没有用
// DestroyIcon(FIconHandle); //不要这个,IDE自动释放FIconHandle,所以加了DestroyIcon反而找不到地址
这个经过我和zjy讨论,觉得niaoge是对的,已经照此修改了。感谢niaoge嘿嘿。
Author:
shenloqi Time: 2007-8-15 10:20
DWORD是标准的一个双字大小的一块内存,不会引用计数和附加其他信息的。BoundsChecker有误报也是正常的,不过如果GetLocaleDataW和GetLocaleDataA这两个函数可能没有对传入的DWORD进行处理,而在此之前有没有对传入的DWORD初始化,倒是可能会有问题,此时使用out因为会给DWORD设初值可能就不会让BoundsChecker误报了,建议检查一下这两个函数是不是没有在所有路径对传入的参数设值,以及检查调用这个函数的地方是不是没有设初值。
Author:
Passion Time: 2007-8-15 12:20
检查了一下,这两个函数是做函数指针用的:
var
GetLocaleDataProc: function (ID: LCID; Flag: DWORD): string;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
GetLocaleDataProc := @GetLocaleDataW
else
GetLocaleDataProc := @GetLocaleDataA;
调用时:
GetLocaleDataProc(AID, LOCALE_SABBREVLANGNAME);
如果加了out,那么调用时传入的参数内容会被忽略,LOCALE_SABBREVLANGNAME又是常量,照理是不能以out的方式传入的。这样加out只会出错。
Author:
shenloqi Time: 2007-8-15 14:25
恩,我也看了一下这个函数,此处是不能加out的。感觉上这两个函数应该不会有什么问题。
BTW:
GetLocaleDataA函数中的SetString(Result, Buffer, GetLocaleInfoA(ID, Flag, Buffer, SizeOf(Buffer)) - 1);看GetLocalInfo的SDK文档,似乎不需要将返回值减一?
Author:
shenloqi Time: 2007-8-22 15:31
小海螺,你用BounderChecker说CnPack的TCnLanguages有问题是在什么环境下测到的?D2007吗?怎么测的?我看了一下代码TCnLanguages和TLanguages的代码是一模一样的,要出错应该大家都出错的啊,要不你试试看写一个程序使用Delphi自己的TLanguages看BounderChecker会不会报D2007的TLanguages也有问题?
Author:
niaoge Time: 2007-8-22 15:36
D2007
Welcome to CnPack Forum (http://bbs.cnpack.org/) |
Powered by Discuz! 5.0.0 |