Привет всем! Немогу понять почему происходит утечка памяти и утечка памяти ли это вообще... Подскажите плиз...
Есть функция GetFileList которая возвращяет список файлов в директории...
Она вызывается по таймеру и следит тем самым что содержание директории изменилось...
Если посмотреть в списке процессов то видно что память занимаемая процессом постоянно растёт... Если закоментировать строку вызывающюю функцию то размер программы увеличивать перестаёт...
Подскажите почему это может происходить? И вообще когда делфи уничтожает екземпляры класса? После выхода из функции? И что происходит в строке запуска функции, происходит копирование или DncList просто получает адресс уже созданного екземпляра класса и где про ето почитать... Заранее спасибо за ответы...
Вызываеться таким образом (лишнее я выкинул):
procedure TFormShablon.TimerTestFolderTimer(Sender: TObject);
var DncList:TStringList;
begin
DncList:=GetFileList('c:\123','*.*');
end;
Сама функция:
Function GetFileList(dir:string='';mask:string='*.*';attr:integer=faAnyFile):TStringList;
var res:cardinal;s:tsearchrec;
begin
result:=TStringList.Create;
if dir='' then dir:=GetCurrentDir;
res:=FindFirst(dir+'/'+mask,attr,s);
while res=0 do begin
result.Append(s.Name);
res:=FindNext(s);
end;
end;
Здравствуйте, deamon_tt, Вы писали:
_>Подскажите почему это может происходить? И вообще когда делфи уничтожает екземпляры класса? После выхода из функции? И что происходит в строке запуска функции, происходит копирование
Нет _>или DncList просто получает адресс уже созданного екземпляра класса
Да _> и где про ето почитать... Заранее спасибо за ответы...
F1, любая толковая книга по Delphi
_>Сама функция: _>Function GetFileList(dir:string='';mask:string='*.*';attr:integer=faAnyFile):TStringList; _>var res:cardinal;s:tsearchrec; _>begin _> result:=TStringList.Create;//Здесь утечка. Кто будет за собой убирать? _> if dir='' then dir:=GetCurrentDir; _> res:=FindFirst(dir+'/'+mask,attr,s); _> while res=0 do begin _> result.Append(s.Name); _> res:=FindNext(s); _> end; _>end;
Если уж так хочется по таймеру то сделай хотя-бы так:
procedure GetFileList(SList: TStringList; dir:string='';mask:string='*.*';attr:integer=faAnyFile);
var res:cardinal;s:tsearchrec;
begin
SList.Clear;
if dir=''then dir:=GetCurrentDir;
res:=FindFirst(dir+'/'+mask,attr,s);
while res=0 do begin
SList.Append(s.Name);
res:=FindNext(s);
end;
end;
//Использованиеprocedure TFormShablon.TimerTestFolderTimer(Sender: TObject);
var DncList:TStringList;
begin//Или создавай свой список в OnCreate формы и уничтожай в OnDestroy
DncList:= TStringList.Create;
try
GetFileList(DncList, 'c:\123', '*.*');
//Что-то делаем со спискомfinally
DncList.Free;
end
end;
А вообще то для такого рода задач есть функции WinAPI FindFirstChangeNotification/FindNextChangeNotification.
Пример использования можно посмотреть в RXLib (модуль RxNotify).
Каждый раз при вызове функции Вы создаете экземпляр класса TStringList, но он остается неосвобожденным до конца работы программы. Отсюда и появляется утечка. Более корректно на мой взгляд было бы передавать в функцию уже созданный экземпляр этого класса. Т.е. переписать код так:
Function GetFileList(dir:string='';mask:string='*.*';attr:integer=faAnyFile; List: TstringList): Cardinal;
var res:cardinal;s:tsearchrec;
beginresult:=-1;
if not Assigned(List) then
begin
result:=0;
Exit;
end;if dir=''then dir:=GetCurrentDir;
res:=FindFirst(dir+'/'+mask,attr,s);
while res=0 do beginList.Append(s.Name);
res:=FindNext(s);
end;
end;
Здравствуйте, SeLarin, Вы писали:
SL>Каждый раз при вызове функции Вы создаете экземпляр класса TStringList, но он остается неосвобожденным до конца работы программы. Отсюда и появляется утечка. Более корректно на мой взгляд было бы передавать в функцию уже созданный экземпляр этого класса. Т.е. переписать код так:
Я бы даже упростил жизнь пользователям:
Function GetFileList(Dir : string=''; Mask : string = '*.*'; Attr : integer = faAnyFile; List: TStrings): Cardinal;
var
res: Cardinal;
s: TSearchRec;
begin
if not Assigned(List) then
begin
Result:=0;
Exit;
end;
Result:= $FFFFFFFF;
if dir = ''then dir:= GetCurrentDir;
res := FindFirst(Dir+'/'+Mask, Attr, s);
While res = 0 do
begin
List.Append(s.Name);
res:= FindNext(s);
end;
end;
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, SeLarin, Вы писали:
SL>>Каждый раз при вызове функции Вы создаете экземпляр класса TStringList, но он остается неосвобожденным до конца работы программы. Отсюда и появляется утечка. Более корректно на мой взгляд было бы передавать в функцию уже созданный экземпляр этого класса. Т.е. переписать код так:
S>Я бы даже упростил жизнь пользователям: S>
Здравствуйте, wildwind, Вы писали:
W>Кроме всего вышесказанного, утечка происходит еще из-за того, что не вызывается FindClose.
если честно, то даже не всматривался...
сразу кинулось в глаза отсутствие освобождения стринг листа и в последнем посте отсутствие дефаулт в послетнем поле (при наличии его в предыдущих)