Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.07.2010, 00:48   #1
Anfall
Форумчанин
 
Регистрация: 10.02.2009
Сообщений: 181
По умолчанию Просьба проверить, если в коде утечка памяти

Всем привет. Я пока очень начинающий программер. Нашел в инете функцию. Кто-то сказал, есть утечка памяти в ней. Не могли бы вы проверить, есть ли она на самом деле и как ее избежать:

Код:
function GetFiles(Path:String; Full: Boolean = False):TStrings;
   Var
   Rec:TSearchRec;
   TMP:TStrings;
   ls,ex: String;
   i: integer;
   ok: integer;
begin
Result:=TStringList.Create;
if Path[Length(Path)]<>'\' Then Path:=Path+'\';
  //ChDir(Path);
ok:=FindFirst(Path+'\*.*',faAnyFile,Rec);
while ok=0 do
begin
if (Rec.Name<>'.')and(Rec.Name<>'..') then
if (Rec.Attr and faDirectory) <> 0 then begin
TMP:=GetFiles(Path+Rec.Name,True);
Result.AddStrings(TMP);
TMP.Free;
end else
begin
ex:=ExtractFileExt(Rec.Name);
if ex='.txt' then
Result.Add(Path+Rec.Name);
end;
ok:=FindNext(Rec);
end;
end;
Заранее благодарен!
Anfall вне форума Ответить с цитированием
Старый 25.07.2010, 11:25   #2
Grag
А может и не...
Участник клуба
 
Аватар для Grag
 
Регистрация: 27.03.2010
Сообщений: 1,269
По умолчанию

Anfall, при каждом вызове функции ты создаешь
Код:
Result:=TStringList.Create;
а уничтожать созданный стринглист??? Вот и утечка памяти....
Перемешивай дело с бездельем и не сойдешь с ума...
Grag вне форума Ответить с цитированием
Старый 25.07.2010, 11:52   #3
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Anfall, попробуй добавить это:
Код:
function GetFiles(Path:String; Full: Boolean = False):TStrings;
   Var
   Rec:TSearchRec;
   TMP:TStrings;
   ls,ex: String;
   i: integer;
   ok: integer;
begin
Result:=TStringList.Create;
if Path[Length(Path)]<>'\' Then Path:=Path+'\';
  //ChDir(Path);
ok:=FindFirst(Path+'\*.*',faAnyFile,Rec);
while ok=0 do
begin
if (Rec.Name<>'.')and(Rec.Name<>'..') then
if (Rec.Attr and faDirectory) <> 0 then begin
TMP:=GetFiles(Path+Rec.Name,True);
Result.AddStrings(TMP);
TMP.Free;
end else
begin
ex:=ExtractFileExt(Rec.Name);
if ex='.txt' then
Result.Add(Path+Rec.Name);
end;
ok:=FindNext(Rec);
end;
 Result.Free;
end;
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 25.07.2010, 17:46   #4
DomiNick
Студент, не
Старожил
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Сообщений: 2,067
Лампочка

Хм... Несколько странноватая функция... Да ещё и рекурсивная...
Я бы её в процедуру переделал:

Код:
Procedure GetFiles_New(Path: String; Items: TStrings);
Var Rec: TSearchRec; ex: String; ok: Integer;
Begin
If (Path[Length(Path)]<>'\') Then
      Path:=Path+'\';
ok:=FindFirst(Path+'\*.*', faAnyFile,Rec);
While (ok=0) Do
      Begin
      If (Rec.Name<>'.') And (Rec.Name<>'..') Then
            If ((Rec.Attr And faDirectory)<>0) Then
                  Begin
                  GetFiles_New(Path+Rec.Name, Items);
                  End
            Else
                  Begin
                  ex:=ExtractFileExt(Rec.Name);
                  If (ex='.txt') Then
                        Items.Add(Path+Rec.Name);
                  End;
      ok:=FindNext(Rec);
      End;
End;
Для чего там вообще какой-то "Full" не понял... Убрал.
I am the First of Cyber Evolution...
I am the First to Program your Future...
DomiNick вне форума Ответить с цитированием
Старый 26.07.2010, 07:38   #5
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Да, только
Код:
Procedure GetFiles_New(Path: String; var Items: TStrings);
ТСу никогда не возвращай в качестве результата функции сложные типы вроде объектов класса (и желательно не возвращать динамические массивы). Дело в том, что после того как ты выйдешь из функции - уничтожить результат функции будет весьма проблематично и с каждым входом в функцию, памяти будет задействовано все больше и больше.

Цитата:
Да ещё и рекурсивная...
Чем Вам не нравиться рекурсия?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 26.07.2010, 07:45   #6
VintProg
not
Участник клуба
 
Аватар для VintProg
 
Регистрация: 27.06.2009
Сообщений: 1,399
По умолчанию

Цитата:
Дело в том, что после того как ты выйдешь из функции - уничтожить результат функции будет весьма проблематично и с каждым входом в функцию, памяти будет задействовано все больше и больше.
С чего ты это взял? Что при каждом выходе прям резулт не уничтожается, зачем он тогда нужен? Это лишние хлопоты программисту.
VintProg вне форума Ответить с цитированием
Старый 26.07.2010, 08:19   #7
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от VintProg Посмотреть сообщение
С чего ты это взял? Что при каждом выходе прям резулт не уничтожается, зачем он тогда нужен? Это лишние хлопоты программисту.
Ты понял что я написал? И если резулт будет уничтожаться, как ты сможешь им воспользоваться ? Его нужно будет уничтожать явно, а вне функции ты этого сделать не сможешь.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 26.07.2010, 08:23   #8
VintProg
not
Участник клуба
 
Аватар для VintProg
 
Регистрация: 27.06.2009
Сообщений: 1,399
По умолчанию

Цитата:
Сообщение от Utkin Посмотреть сообщение
Ты понял что я написал? И если резулт будет уничтожаться, как ты сможешь им воспользоваться ? Его нужно будет уничтожать явно, а вне функции ты этого сделать не сможешь.
А теперь понял!
VintProg вне форума Ответить с цитированием
Старый 26.07.2010, 08:41   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

полностью согласен с DomiNick и Utkin

подобное использование чрезвычайно чревато.

и, кстати, вот так:
Цитата:
Код:
  Result.Free;
end;
делать нельзя! Только что проверил, При попытке присвоить результат функции получаем Access Violation


Цитата:
Сообщение от VintProg
Что при каждом выходе прям резулт не уничтожается, зачем он тогда нужен?
не буду утверждать на 100%, но, думаю, что результат именно не уничтожается. А иначе как бы он был бы доступен ВНЕ функции?!
впрочем, не удивлюсь, если сработает и такой механизм:
Код:
  var TS : TString;
...
   TS := функция();
пользуемся TS
после использования:
   TS.Free;
но вообще зачем придумывать себе проблемы?!! Как было предложено выше: Переделать функцию в процедуру, передавать в неё указатель на созданный ранее экземпляр класса и наслаждаться надёжной (и прозрачной) работой программы!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 26.07.2010, 09:07   #10
DomiNick
Студент, не
Старожил
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Сообщений: 2,067
По умолчанию

Цитата:
Да, только
Код:
Procedure GetFiles_New(Path: String; var Items: TStrings);
Хм! По логике - да, но ведь работает же и без.....
Цитата:
Чем Вам не нравиться рекурсия?
Рекурсия мне нравится...
Но не при поиске файлов...
I am the First of Cyber Evolution...
I am the First to Program your Future...
DomiNick вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Indy в потоке - утечка памяти PUH Фриланс 5 28.12.2009 14:06
Indy в потоке - утечка памяти PUH Помощь студентам 0 25.12.2009 12:27
Утечка памяти при работе с GDI+ Ivan_32 Общие вопросы C/C++ 2 29.11.2009 00:12
утечка памяти в С++ vengo Общие вопросы C/C++ 9 10.06.2008 21:24
DrawState - утечка памяти? unnamed Win Api 2 11.04.2007 18:36