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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 28.01.2018, 16:56   #1
Taras2018
Пользователь
 
Аватар для Taras2018
 
Регистрация: 13.01.2018
Сообщений: 47
По умолчанию Утечка памяти / out of memory

Добрый день, уважаемые пользователи.
Суть проблемы: При запуске процедуры идет замена слов в файле размеров в 400 мегабайт. И после 5-10 секунд выскакивает окно out of memory. Хотя файлы до 200 мегабайт обрабатывает.

Я так понял что это из за недостатка выделенной памяти на массив, строку. Какие ошибки допущены в коде и как решить эту проблему?
Код:
procedure Tfrm_Main.Run;
var afList: TStringDynArray;
    i, j, k: integer;
    L, rL, fL: TStringList;
    NewName, tmp: String;

begin
 memo_Log.Lines.Add(Format('Начало обработки: %s', [DateTimeToStr(Now)]));
 memo_Log.Lines.Add('///');
 memo_Log.Lines.Add('');
 L := TStringList.Create;
 for i := 0 to memo_Folders.Lines.Count - 1 do
  
begin
   afList := TDirectory.GetFiles(memo_Folders.Lines[i], '*.txt', SO);
   for j := 0 to Length(afList) - 1 do
    L.Add(afList[j]);
  end;
 rL := TStringList.Create;
 rL.Text := Trim(memo_List.Text);
 k := 0;
 fL := TStringList.Create;
 for i := 0 to L.Count - 1 do
  
begin
   memo_Log.Lines.Add(Format('Обработка файлов %s', [L.Strings[i]]));
   fL.LoadFromFile(L.Strings[i]);
   tmp := ExtractFileName(L.Strings[i]);
   tmp := Copy(tmp, 1, Pos('.', tmp) - 1);
   NewName := Format('%s%s.%s', [ExtractFilePath(L.Strings[i]),
                                     tmp,
                                     FormatDateTime('ddmmyy_hhnn', Now)]);
   
if rg_Order.ItemIndex = 1 then
    for j := 0 to rL.Count - 1 do
     rL.Exchange(j, RandomRange(0, rL.Count));
   for j := 0 to fL.Count - 1 do
    begin
     fL.Strings[j] := StringReplace(fL.Strings[j], edt_Word.Text, rL.Strings[k], RF);
     inc(k);
     if k = rL.Count then k := 0;
    end;
   fL.SaveToFile(NewName);
   memo_Log.Lines.Add(Format('Сохранение под именем %s', [NewName]));
   memo_Log.Lines.Add('');
  end;
 memo_Log.Lines.Add('///');
 memo_Log.Lines.Add(Format('Окончание обработки: %s', [DateTimeToStr(Now)]));
 fL.Free;
 rL.Free;
 L.Free;
 btn_Next.Enabled := false;
 LoadBMP(btn_Prev, 5);
 btn_Prev.Caption := 'С начала';
end;
Taras2018 вне форума Ответить с цитированием
Старый 31.01.2018, 12:52   #2
Taras2018
Пользователь
 
Аватар для Taras2018
 
Регистрация: 13.01.2018
Сообщений: 47
По умолчанию

Проблема решена, использовал функцию ExtractFileExt. Всем спасибо за внимание.
Taras2018 вне форума Ответить с цитированием
Старый 31.01.2018, 13:05   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от Taras2018 Посмотреть сообщение
Проблема решена, использовал функцию ExtractFileExt.
она максимум вам помогает взять расширение файла, ошибка вылетала при чтении файла, ибо вы его целиком грузите в память.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 31.01.2018, 13:48   #4
Taras2018
Пользователь
 
Аватар для Taras2018
 
Регистрация: 13.01.2018
Сообщений: 47
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
она максимум вам помогает взять расширение файла, ошибка вылетала при чтении файла, ибо вы его целиком грузите в память.
Эта функция + построчное чтение без загрузки в память всего файла через Assing = результат.

Последний раз редактировалось Taras2018; 31.01.2018 в 14:02.
Taras2018 вне форума Ответить с цитированием
Старый 11.09.2018, 13:19   #5
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
По умолчанию

Цитата:
Сообщение от Taras2018 Посмотреть сообщение
Добрый день, уважаемые пользователи.
Суть проблемы: При запуске процедуры идет замена слов в файле размеров в 400 мегабайт. И после 5-10 секунд выскакивает окно out of memory. Хотя файлы до 200 мегабайт обрабатывает.

Я так понял что это из за недостатка выделенной памяти на массив, строку. Какие ошибки допущены в коде и как решить эту проблему?
Код:
procedure Tfrm_Main.Run;
var afList: TStringDynArray;
    i, j, k: integer;
    L, rL, fL: TStringList;
    NewName, tmp: String;

begin
 memo_Log.Lines.Add(Format('Начало обработки: %s', [DateTimeToStr(Now)]));
 memo_Log.Lines.Add('///');
 memo_Log.Lines.Add('');
 L := TStringList.Create;
 for i := 0 to memo_Folders.Lines.Count - 1 do
  
begin
   afList := TDirectory.GetFiles(memo_Folders.Lines[i], '*.txt', SO);
   for j := 0 to Length(afList) - 1 do
    L.Add(afList[j]);
  end;
 rL := TStringList.Create;
 rL.Text := Trim(memo_List.Text);
 k := 0;
 fL := TStringList.Create;
 for i := 0 to L.Count - 1 do
  
begin
   memo_Log.Lines.Add(Format('Обработка файлов %s', [L.Strings[i]]));
   fL.LoadFromFile(L.Strings[i]);
   tmp := ExtractFileName(L.Strings[i]);
   tmp := Copy(tmp, 1, Pos('.', tmp) - 1);
   NewName := Format('%s%s.%s', [ExtractFilePath(L.Strings[i]),
                                     tmp,
                                     FormatDateTime('ddmmyy_hhnn', Now)]);
   
if rg_Order.ItemIndex = 1 then
    for j := 0 to rL.Count - 1 do
     rL.Exchange(j, RandomRange(0, rL.Count));
   for j := 0 to fL.Count - 1 do
    begin
     fL.Strings[j] := StringReplace(fL.Strings[j], edt_Word.Text, rL.Strings[k], RF);
     inc(k);
     if k = rL.Count then k := 0;
    end;
   fL.SaveToFile(NewName);
   memo_Log.Lines.Add(Format('Сохранение под именем %s', [NewName]));
   memo_Log.Lines.Add('');
  end;
 memo_Log.Lines.Add('///');
 memo_Log.Lines.Add(Format('Окончание обработки: %s', [DateTimeToStr(Now)]));
 fL.Free;
 rL.Free;
 L.Free;
 btn_Next.Enabled := false;
 LoadBMP(btn_Prev, 5);
 btn_Prev.Caption := 'С начала';
end;
у вас утечки памяти в TStringList, вы их освобождаете, а содержимое нет
PTyTb32 вне форума Ответить с цитированием
Старый 11.09.2018, 13:38   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Цитата:
у вас утечки памяти в TStringList, вы их освобождаете, а содержимое нет
Чего это? Free и память под строки освождает
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 11.09.2018, 13:52   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

PTyTb32, а что это Вы вдруг решили тему более чем полугодовой давности поднять?

p.s. с ответом Аватар согласен.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти Алексей0001 Общие вопросы Delphi 8 02.02.2018 23:17
Утечка памяти [Освобождение памяти массива] denis76560 Общие вопросы Delphi 4 27.11.2016 18:20
Утечка памяти. Gdasar C++ Builder 15 09.02.2016 08:56
Memory leak (Утечка памяти) andrejjka Общие вопросы Delphi 3 11.02.2011 14:39
Утечка памяти ZvEr_HaCkEr Свободное общение 13 24.09.2010 19:30