内存泄漏,附源码,分数不多,求帮助

hansen_chen 2010-09-06 12:16:48
最近在写一套系统,用了ADO,想增加一些功能,改写ADOQuery控件,再系统调试时发现内存泄漏,烦请各位前辈帮忙修改。
控件完整源码如下:
unit ADOMacQuery;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ADODB, DBTables;

type
TADOMacQuery = class(TADOQuery)
private
FKeyField: string;
FMacParams: TParams;
FMacSQL: TStrings;
procedure SetMacParams(Value: TParams);
procedure SetMacSQL(Value: TStrings);
procedure MacSQLChanged(Sender: TObject);
protected
procedure ExpandMacs; dynamic;
procedure OpenCursor(InfoQuery: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function ParamByN(const Value: string): TParam;
procedure ExecSQL;
procedure ReQuery();
published
property SQL: Tstrings read FMacSQL write SetMacSQL;
property Parameters: TParams read FMacParams write SetMacParams;
property KeyField: string read FKeyField write FKeyField;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('SelfControl', [TADOMacQuery]);
end;

constructor TADOMacQuery.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

FMacSQL := TStringList.Create;
TStringList(FMacSQL).OnChange := MacSQLChanged;
FMacParams := TParams.Create(self);
ParamCheck := False;
end;

destructor TADOMacQuery.Destroy;
begin
FreeAndNil(FMacSQL);
FreeAndNil(FMacParams);
inherited Destroy;
//FMacParams.Free;
end;

procedure TADOMacQuery.SetMacParams(Value: TParams);
begin
FMacParams.AssignValues(Value);
end;

function TADOMacQuery.ParamByN(const Value: string): TParam;
begin
Result := FMacParams.ParamByName(Value);
end;

procedure TADOMacQuery.SetMacSQL(Value: TStrings);
begin
if FMacSQL.Text = Value.Text then
Exit;

// Disconnect;
FMacSQL.BeginUpdate;
try
FMacSQL.Assign(Value);
finally
FMacSQL.EndUpdate;
end;
end;

procedure TADOMacQuery.MacSQLChanged(Sender: TObject);
var
List: TParams;
i: integer;
begin
if (csReading in ComponentState) then
Exit;

List := TParams.Create(Self);
try
{FText :=}List.ParseSQL(FMacSQL.Text, True);
List.AssignValues(FMacParams);
for i := List.Count - 1 downto 0 do
if List[i].DataType = ftUnknown then
begin
List[i].DataType := ftString;
List[i].AsString := '';
end;
FMacParams.Clear;
FMacParams.Assign(List);
finally
List.Free;
end;
end;

procedure TADOMacQuery.OpenCursor(InfoQuery: Boolean);
begin
ExpandMacs;
inherited OpenCursor(InfoQuery);{{*************地址指向这里***************}}
end;

procedure TADOMacQuery.ExecSQL;
begin
ExpandMacs;
inherited ExecSQL;
end;

procedure TADOMacQuery.ExpandMacs;
var
i: integer;
tsSQL, tsValue: string;
begin
tsSQL := FMacSQL.GetText(); {*************地址指向这里***************}
for i := FMacParams.Count - 1 downto 0 do
begin
case FMacParams[i].DataType of
ftDate: tsValue := '''' + FormatDatetime('yyyy-mm-dd',
FMacParams[i].AsDate) + '''';
else
tsValue := FMacParams[i].AsString;
end;
tsSQL := StringReplace(tsSQL, ':' + FMacParams[i].Name
, tsValue, [rfReplaceAll, rfIgnoreCase]);
end;
inherited SQL.SetText(PChar(tsSQL));
end;

procedure TADOMacQuery.ReQuery();
var
SavePlace: TBookMark;
KeyValue: Variant;
begin
//浏览窗口刷新数据,并恢复记录指针
SavePlace := nil;
DisableControls;
try
if FKeyField = 'RecNo' then
begin
if not IsEmpty then
SavePlace := GetBookmark;
end
else if FKeyField <> '' then
KeyValue := FieldByName(FKeyField).Value;
Close;
Open;
if FKeyField = 'RecNo' then
begin
if SavePlace <> nil then
begin
try
if BookmarkValid(SavePlace) then
GotoBookmark(SavePlace);
finally
FreeBookmark(SavePlace);
end;
end;
end
else if FKeyField <> '' then
Locate(FKeyField, KeyValue, []);
finally
EnableControls;
end;
end;

end.


泄漏情况:
一个内存块已泄露. 大小是: 36

该内存块分配于线程 0x1714, 当时的堆栈跟踪(返回地址):
402E4C
40E45D
40E499
423AF9
4C3FE3
4C3FAE
48E407
48E252
4C43BB
44AD0A
44108D

该内存块当前被用于一个属于以下类的对象: 未知

...全文
62 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hansen_chen 2010-09-07
  • 打赏
  • 举报
回复
是FMacSQL.GetText(),这边分配了内存,没有释放。已解决了,谢谢大家的回复。
hongqi162 2010-09-07
  • 打赏
  • 举报
回复
注意create后要free
kye_jufei 2010-09-06
  • 打赏
  • 举报
回复
FMacSQL.GetText(),函数有分配内存,没有释放掉;要FREE...

finally
StrDispose(Buffer);
end;
newfang 2010-09-06
  • 打赏
  • 举报
回复
代码太多,分又少·~看着晕

如果不想多出分,断点跟踪一下,把出问题那部分代码贴出来就行了~~

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧