Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с утечкой памяти, в TList (Список из форм) 
:(
    Опции темы
Teran
  Дата 24.3.2006, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Есть две формы первая - главная с таймером который создает список из форм
а вторая - которая буде находится в списке

в событии OnTimer пишу
Код

procedure TForm1.TimerMonitorTimer(Sender: TObject);
var
i,i1:integer;
TmpForm:TForm2;
ListOfForm:TList;
begin
ListOfForm:=TList.Create;
for i:=0 to 10 do                          // создаю список из 10 форм
begin
   TmpForm:=TForm2.Create(nil);
   TmpForm.Caption:='Test';
  
   for i1:=0 to 5 do                        //создаю список в другой форме из пяти элементов 
    begin
      New(TmpForm.Item);               
      TmpForm.Item.Str:='Test1';      
      TmpForm.Item.Str2:='Test2';

      TmpForm.CLSIDList.Add(TmpFormList.CLSID);
    end;

   ListOfForm.Add(TmpForm);
end;
             //Очистка памяти 
for i:=0 to ListOfForm.Count-1 do     
 begin
  for i1:=0 to TForm2(ListOfForm[i]).ItemList.Count-1 do
       begin
        Dispose(TForm2(ListOfForm[i]).ItemList[i1]);    //удаляю список из второй формы
       end;
  TForm2(ListOfForm[i]).Free;    //удаляю формы
 end;

ListOfForm.Free;
end;


Форма 2 имеет тоже свой список
Код

.........
type
   TForm2TmpList=record
    Str1:String;
    Str2:String;
  end;
   PForm2TmpList=^TForm2TmpList;

  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
  public
    Item:PForm2TmpList;
    ItemList:TList;
  end;

var
  Form2: TForm2;

implementation
uses Unit1;
{$R *.dfm}

procedure TFormList.FormCreate(Sender: TObject);
begin
ItemList:=TList.Create;
end;

procedure TFormList.FormDestroy(Sender: TObject);
begin
ItemList.Free;
end;

end;


если будет включен таймер то в процессах моя прога будат расти в памяти неизвнстнопочему
smile smile smile
я знаю что в чужом коде трудно разобраться но кто сможет помогите найти ошибку очистки памяти!


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Snowy
Дата 24.3.2006, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Цитата(Teran @ 24.3.2006, 17:39 Найти цитируемый пост)
      TmpForm.CLSIDList.Add(TmpFormList.CLSID);
Вот эта строка сбивает с толку.
Она здесь совсем не смотрится.
PM MAIL   Вверх
Teran
Дата 24.3.2006, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Ой прошу прощения вместо неё должно быть
Код

 TmpForm.ItemList.Add(TmpFormList.CLSID);

просто писал вручную и ошибся

этой строкой я создаю список из 5 элементов в каждой из созданных форм
Добавлено @ 18:37
да чтож такое опять ошибся
вот так должно быть
Код

TmpForm.ItemList.Add(TmpFormList.Item);



--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Teran
Дата 24.3.2006, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Получается что каждый елемент списка из форм (ListOfForm)
содержит вложенный список (ItemList) из двух строк


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Snowy
Дата 24.3.2006, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Лучше так:
Код
             //Очистка памяти 
for i:=ListOfForm.Count-1 downto  do
begin
  TForm2(ListOfForm[i]).Free;
  ListOfForm.Delete(i);
end;

Код

procedure TFormList.FormDestroy(Sender: TObject);
var
  i: integer;
begin
  for i := ItemList.Count - 1 downto 0 do
    Dispose(ItemList[i]);
  ItemList.Free;
end;

Добавлено @ 19:05
Надеюсь, ListOfForm у тебя глобальная переменная?
PM MAIL   Вверх
Teran
Дата 24.3.2006, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Цитата(Snowy @ 24.3.2006, 19:04 Найти цитируемый пост)
Надеюсь, ListOfForm у тебя глобальная переменная?

нет
а зачем ведь она создается и удаляется в обработчике таймера



Цитата(Snowy @ 24.3.2006, 19:04 Найти цитируемый пост)
Лучше так:


ты знаеш попробывал очищать так как ты написал а память кушает всеравно


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Демо
Дата 24.3.2006, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



А что такое TmpFormList?


--------------------
    
PM MAIL ICQ Skype   Вверх
Snowy
Дата 24.3.2006, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Проблема в принципе не сложная.
Все дело в string.
У тебя
Код
   TForm2TmpList=record    
    Str1:String;    
    Str2:String;    
  end;

В этом и проблема. т.к. string - это указатель.
Указатели убиваются, а их память - нет.
Решить вопрос просто:
Код
   TForm2TmpList=record    
    Str1: ShortString;    
    Str2: ShortString;    
  end;

PM MAIL   Вверх
Демо
Дата 24.3.2006, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



Цитата(Snowy @ 24.3.2006, 20:37 Найти цитируемый пост)
В этом и проблема. т.к. string - это указатель.
Указатели убиваются, а их память - нет.


Память очищается, так как ссылок на эти строки больше не существует.

Проверь сам:

Код

type
  PRec=^TRec;
  TRec=record
    Str1:String;
  end;

var
  R: PRec;

procedure TForm1.Button3Click(Sender: TObject);
begin
  New(R);
  SetLength(R.Str1,1024*1024*50);
  ZeroMemory(@R.Str1[1],Length(R.Str1));
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Dispose(R);
end;






--------------------
    
PM MAIL ICQ Skype   Вверх
Snowy
Дата 25.3.2006, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Демо, ы предлагаеь тривиальную задачу, с которой дельфийский сборщик мусора справляется на раз.
Давай ее усложним:
Код
var
  p: PRec;
  l: TList;
  i: integer;
begin
  l := TList.Create;
  for i := 0 to 99 do
  begin
    New(p);
    p.Str1 := 'Test';
    l.Add(p);
  end;
  for i := 0 to 99 do
    Dispose(l[i]);
  l.Free;
end;

Вот тут сборщик мусора теряет ссылку на стринги.
И память начинает утекать...
PM MAIL   Вверх
Демо
Дата 25.3.2006, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



Цитата(Snowy @ 25.3.2006, 00:26 Найти цитируемый пост)
Вот тут сборщик мусора теряет ссылку на стринги.
И память начинает утекать...


Потому что структура - это не классовый объект. У него нет предка, который позаботился бы об уничтожении потомка.

В данном случае утечка памяти - ошибка программиста.
Достаточно заменить
Код

    Dispose(l[i]);
на
Код

    Dispose(PRec(l[i]));


для явного приведения типа, и никакой утечки не будет.


--------------------
    
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0566 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.