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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.02.2012, 21:10   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию Списки. Присвоение илемента по индексу. Удаляется или в никуда?

Доброго времени суток!

Реализуя очередной класс:
Код:
type
  tFListMgr=class(TList)
    private
      procedure SetItem(aIndex:Integer; aItem:TFileInfo);
      function GetItem(aIndex:Integer):TFileInfo;
    public
      property Files[aIndex:Integer]:TFileInfo read GetItem write SetItem;
  end;

implementation

{ tFListMgr }

function tFListMgr.GetItem(aIndex: Integer): TFileInfo;
begin
  Result:=Items[aIndex];
end;

procedure tFListMgr.SetItem(aIndex: Integer; aItem: TFileInfo);
begin
  Items[aIndex]:=aItem;
end;
Интересует этот момент:
Код:
procedure tFListMgr.SetItem(aIndex: Integer; aItem: TFileInfo);
begin
  Items[aIndex]:=aItem;
end;
Теряю ли я память при таком действии?
Если да, то как правильно?

Последний раз редактировалось Человек_Борща; 26.02.2012 в 21:26.
Человек_Борща вне форума Ответить с цитированием
Старый 26.02.2012, 22:33   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В SetItem просто запоминается адрес aItem. Если TFileInfo RECORD из QTypes, то должно выглядеть: Items[aIndex]:=Addr(aItem); сам объект нельзя удалять после этого, иначе при обращении к GetItem будет шах и мат
В GetItem соответственно: Result:=PFileInfo(Items[aIndex])^;

Потери будут при удалении итемов из List без освобождения памяти занятой под TFileInfo
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 26.02.2012, 22:39   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

вообще-то мой TFileInfo это TObject... пока остановился на аком варианте:
Код:
procedure TFListMgr.SetItem(aIndex: Integer; aItem: TFileInfo);
begin
  TFileInfo(Items[aIndex]).Free;
  Insert(aIndex, aItem);
  // Items[aIndex]:=aItem;
end;
Человек_Борща вне форума Ответить с цитированием
Старый 26.02.2012, 22:43   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Insert и закомментированный участок равнозначны
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 26.02.2012, 22:46   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Если TFileInfo это экземпляр некоего класса и Ваш наследник от TList просто хранит ссылку на созданный экземпляр (и больше этот экземпляр нигде не учитывается), то
Код:
List.items[2] := TfileInfo.create;
List.items[2] := TfileInfo.create; // <--
по стрелке теряем память, ведь её никто не чистит.
Я в таких случаях переопределяю метод Add и не присваиваю в Items напрямую экземпляров. Если надо напрямую то можно написать доп. метод, который сперва освобождает старый объект а потом кладёт новый.
А вообще если беспокойство о памяти, то ручками всё выверять в подобных методах, но это уже надо на постановку задачи смотреть, не всегда оправдана чистка объекта, бывают ведь и двойные ссылки, лист может просто хранит для каких-то целей. Я обычно реальное хранилище оборачиваю во что-то вроде фабрики, а остальные потребители могут просто хранить ссылку на объекты и только читать из хранилища фабрики нужные экземпляры.
phomm вне форума Ответить с цитированием
Старый 27.02.2012, 23:25   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Я храню Tobject в Tlist.
Надо ли мне делать так:
Код:
procedure TFListMgr.SetItem(aIndex: Integer; aItem: TFileInfo);
begin
  TFileInfo(Items[aIndex]).Free;//?
  Insert(aIndex, aItem);
end;
Человек_Борща вне форума Ответить с цитированием
Старый 27.02.2012, 23:43   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Если у вас больше нигде нет указателя на замещаемый объект, то это остается единственным местом где его можно и нужно убить. Иначе будут утечки. Только Insert неуместно, если замещаете. Вставит по индексу aIndex, а то что там раньше было станет по индексу aIndex+1. То что в #3 закоментировали и будет замещением, а Insert вставка с раздвиганием. В #4 я чепуху написал
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 27.02.2012 в 23:52.
Аватар вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Однонаправленные списки на с или с++ irina700000 Помощь студентам 0 28.01.2012 09:39
Обращение к массиву по индексу Morgusha Помощь студентам 2 28.10.2009 15:03
Поиск по индексу (Delphi) VadEr Помощь студентам 0 06.10.2009 19:03
Поток в никуда... prizrak1390 Работа с сетью в Delphi 1 30.06.2008 10:32
Быстрый поиск по индексу valerij Microsoft Office Excel 1 21.04.2008 11:04