内存泄露 问题(10分)

  • 主题发起人 主题发起人 meme258
  • 开始时间 开始时间
M

meme258

Unregistered / Unconfirmed
GUEST, unregistred user!
下面这个函数,我程序中调用N次,最后返回 的TStringList 没有释放,这个程序运行时间长了以后就停止不动了,用FASTMM的话,报告有 内存泄露,
如果在这个程序的最后,.free 的话,程序就报错,,,,
请教高手,

function QuDeXXUrl(var code:string;kzf,jzf:string):TStringList ;
var
urlList:TStringList;
u_code,liurl,url_xh:string;
u_k,u_j,uu:Integer;
begin
urlList := TStringList.Create;
u_code := code;
if Pos(kzf,u_code) = 0 then
begin
ShowMessage('网址开始位置错误,源代码中没有这些字符');
Result := nil;
Exit;
end;
if Pos(jzf,u_code) = 0 then
begin
ShowMessage('网址结束位置错误,源代码中没有这些字符');
Result := nil;
Exit;
end;

while Pos(kzf,u_code) <> 0 do
begin
u_k := Pos(kzf,u_code);
u_code := Copy(u_code,u_k,Length(u_code)-u_k);
u_k := Pos(kzf,u_code);

u_j := Pos(jzf,u_code);

liurl := Copy(u_code,u_k + Length(kzf),u_j-u_k-Length(kzf));
url_xh := StringReplace(liurl,'http://www.readnovel.com/novel/','',[rfReplaceAll]);
uu := Pos('/',url_xh);
url_xh := Copy(url_xh,0,uu-1);
u_code := Copy(u_code,u_j,Length(u_code)-u_j);
if Pos(url_xh,urlList.Text) = 0 then
urlList.Add(liurl);
end;
Result := urlList;
//urlList.Free;
//urlList := nil;
//FreeAndNil(urlList);
end;​
 
1. 去掉urlList : TStringList定义!
2. urlList := TStringList.Create;改为
result := TStringList.Create;
3.有后面urlList读该为Result
4.下面的去掉
Result := urlList;
//urlList.Free;
//urlList := nil;
//FreeAndNil(urlList);

OK!
 
建议把STRINGlIST设置为公有变量
做个过程,重新赋值前先CLEAR
 
function QuDeXXUrl(var code: string; kzf, jzf: string): TStringList;
var
u_code, liurl, url_xh: string;
u_k, u_j, uu: Integer;
begin
u_code := code;
if Pos(kzf, u_code) = 0 then
begin
ShowMessage('网址开始位置错误,源代码中没有这些字符');
if Result <> nil then
Result.Free;
Result := nil;
Exit;
end;
if Pos(jzf, u_code) = 0 then
begin
ShowMessage('网址结束位置错误,源代码中没有这些字符');
if Result <> nil then
Result.Free;
Result := nil;
Exit;
end;

if Result = nil then
Result := TStringList.Create
else
Result.Clear;

while Pos(kzf, u_code) <> 0 do
begin
u_k := Pos(kzf, u_code);
u_code := Copy(u_code, u_k, Length(u_code) - u_k);
u_k := Pos(kzf, u_code);

u_j := Pos(jzf, u_code);

liurl := Copy(u_code, u_k + Length(kzf), u_j - u_k - Length(kzf));
url_xh := StringReplace(liurl, 'http://www.readnovel.com/novel/','',[rfReplaceAll]);
uu := Pos('/', url_xh);
url_xh := Copy(url_xh, 0, uu - 1);
u_code := Copy(u_code, u_j, Length(u_code) - u_j);
if Pos(url_xh, Result.Text) = 0 then
Result.Add(liurl);
end;
end;
 
谢谢楼上兄弟,
好像不行,看了你改过的代码,我发现, 下面这个函数也有 内存泄露,加上

if Result = nil then
Result := TStringList.Create
else
Result.Clear;
这一段代码的话,就报错 USER32.DLL 模块错误什么的。
function Split(ss,s:string): TStringList;
begin
Result := TStringList.Create;
while Pos(s,ss)>0 do
begin
Result.Add(Copy(ss,1,Pos(s,ss)-1));
Delete(ss,1,Pos(s,ss) + Length(s) - 1);
end;
Result.Add(ss);
end;
 
打开Delphi再仔细研究了一下,程序应该这样写
function QuDeXXUrl(var code: string; kzf, jzf: string): TStringList;
var
u_code, liurl, url_xh: string;
u_k, u_j, uu: Integer;
begin
u_code := code;
Result := nil;
if Pos(kzf, u_code) = 0 then
begin
ShowMessage('网址开始位置错误,源代码中没有这些字符');
if Result <> nil then
Result.Free;
Exit;
end;
if Pos(jzf, u_code) = 0 then
begin
ShowMessage('网址结束位置错误,源代码中没有这些字符');
if Result <> nil then
Result.Free;
Exit;
end;

Result := TStringList.Create;

while Pos(kzf, u_code) <> 0 do
begin
u_k := Pos(kzf, u_code);
u_code := Copy(u_code, u_k, Length(u_code) - u_k);
u_k := Pos(kzf, u_code);

u_j := Pos(jzf, u_code);

liurl := Copy(u_code, u_k + Length(kzf), u_j - u_k - Length(kzf));
url_xh := StringReplace(liurl, 'http://www.readnovel.com/novel/','',[rfReplaceAll]);
uu := Pos('/', url_xh);
url_xh := Copy(url_xh, 0, uu - 1);
u_code := Copy(u_code, u_j, Length(u_code) - u_j);
if Pos(url_xh, Result.Text) = 0 then
Result.Add(liurl);
end;
end;
 
不过这样写,真是会有内存泄漏的,比喻你已经创建了变量,又再调用这个函数,重新赋值,那么原来创建没有撤销,所以就泄漏了。

begin
SL:=TStringList.Create;//这里已经新建,占了内存
if SL <> nil then
SL.Clear;
SL:=QuDeXXUrl(code, '1', '1');//这里又新建,前面占的内存没释放
if SL<>nil then
SL.Free;
end;

换成下面的写法,你去研究一下吧

procedure QuDeXXUrl(var code: string; kzf, jzf: string; SL:TStringList);
var
u_code, liurl, url_xh: string;
u_k, u_j, uu: Integer;
begin
u_code := code;

if Pos(kzf, u_code) = 0 then
begin
ShowMessage('网址开始位置错误,源代码中没有这些字符');
if SL <> nil then
SL.Free;
SL:=nil;
Exit;
end;
if Pos(jzf, u_code) = 0 then
begin
ShowMessage('网址结束位置错误,源代码中没有这些字符');
if SL <> nil then
SL.Free;
SL:=nil;
Exit;
end;

SL := TStringList.Create;

while Pos(kzf, u_code) <> 0 do
begin
u_k := Pos(kzf, u_code);
u_code := Copy(u_code, u_k, Length(u_code) - u_k);
u_k := Pos(kzf, u_code);

u_j := Pos(jzf, u_code);

liurl := Copy(u_code, u_k + Length(kzf), u_j - u_k - Length(kzf));
url_xh := StringReplace(liurl, 'http://www.readnovel.com/novel/','',[rfReplaceAll]);
uu := Pos('/', url_xh);
url_xh := Copy(url_xh, 0, uu - 1);
u_code := Copy(u_code, u_j, Length(u_code) - u_j);
if Pos(url_xh, SL.Text) = 0 then
SL.Add(liurl);
end;
end;


调用
QuDeXXUrl(code, kzf, jzf, ss);
 
除非在调用之前

begin
SL:=TStringList.Create;
if SL <> nil then
SL.Free;//先撤销一下
SL:=QuDeXXUrl(code, '1', '1');
if SL<>nil then
SL.Free;
end;

function Split(ss,s:string): TStringList;
道理也是一样吧
 
最好在调用的过程创建TStringList,作为动态参数传给过程
使用完后释放。
TStringList作为类,实例化后不会自动释放
 
谢谢各位,
这个问题,最终在 万一老师的帮助下,解决了,
procedure QuDeNRUrl(var code:string;kzf,jzf:string; var List: TStrings);
加入一个 按引用传递的参数,作为返回值,这样就可以 释放了,

不过,发现,我的程序中还有好多个 内存泄露的地方,
内存泄露直接导致线程自动停止,
 
后退
顶部