С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/37: Рейтинг темы: голосов - 37, средняя оценка - 4.86
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 735
1

Совет по TList

26.03.2013, 00:08. Показов 7129. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет всем. Есть пару вопросов по TList. Изначально расскажу с какой целью я использую его. Я получаю с GPS приемника координаты каждую секунду и мне необходимо хранить широту долготу скорость и так далее эти данные должны хранится на протяжении определенного времени допустим 3600 отчетов а может и того более но пока это не важно.

А теперь вопросы правильно ли я делаю :

Я создаю класс для хранения данных в списке
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type _TGPSData  = record
          Latitude  : Real;
        NSIndicator : String;
          Longitude : Real;
        EWIndicator : String;
           DateTime : String;
end;
....
type TGPSRecordData = class (TObject)
  private
    GPSDRecord : _TGPSData;
  public
    property Data : _TGPSData read GPSDRecord;
  constructor Create(const  GPSDRecord : _TGPSData);
end;
...
{ TGPSRecordData }
 
constructor TGPSRecordData.Create(const GPSDRecord: _TGPSData);
begin
  inherited Create;
  Self.GPSDRecord:=GPSDRecord;
end;


Создаю список таким образом :
Delphi
1
2
3
4
5
6
LGPSList  : TList; //Изначально объявляю список глобально 
....
procedure Tform1.create(Sender: TObject);
begin
LGPSList  :=  TList.Create;
end;
Добавляю в список таким образом
Delphi
1
2
3
4
var TrackGo:_TGPSData;
begin
LGPSList.Add(TGPSRecordData.Create(TrackGo));
end;
Очищаю список таким образом
Delphi
1
2
3
  for i := LGPSList.Count - 1 downto 0 do
    TGPSRecordData(LGPSList[i]).Free;
  LGPSList.Free;
И вот тут почему то память не освобождается. Прошу помочь в понимании что я не так делаю или возможно есть правильные и более красивые методы сохранения информации в памяти что бы можно было быстро к ней обратится. Заранее спасибо за ответы.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.03.2013, 00:08
Ответы с готовыми решениями:

Список.TList
Создание, присвоение, сортировка, и переделывание списка если у кого есть примеры скиньте...

TList и Record
Всем привет. Начал пробовать использовать TList и сразу появились вопросы. Например у нас есть:...

TList и Record
Есть запись TPointSource = record h: float; Lv: float; P: TfPoint; end;...

Работа с TList
почему-то теряется указатель при выборке из Items В главной процедуре после добавления ...

9
Пишу на Delphi...иногда
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
26.03.2013, 00:24 2
можно обойтись без класса
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type _TGPSData  = record
          Latitude  : Real;
        NSIndicator : String;
          Longitude : Real;
        EWIndicator : String;
           DateTime : String;
end;
 
var
   GPSData  :_TGPSData ;
.....
// добавляем в лист
   LGPSList.Add(GetMemory(SizeOf( _TGPSData)));
   CopyMemory(LGPSList[LGPSList.Count-1],@GPSData ,SizeOf( _TGPSData));
 
// получаем значения
    GPSData:=_TGPSData(LGPSList[0]^);
 
// очищаем список
   for i :=0 to LGPSList.Count - 1 do
       FreeMemory(LGPSList[i],SIzeOf( _TGPSData));
  FreeAndNil(LGPSList);
имхо если делать класс, то родителя брать TList и переопределять необходимые методы
1
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 735
26.03.2013, 00:31  [ТС] 3
я часто встречал вместо class-а использовали просто record. Такого плана
Delphi
1
2
3
4
5
6
7
8
point = record
end;
 
k = ^point
 
...
new(k);
TList.add(k);
Может лучше его использовать ? я просто смущаюсь с такими методами на сколько они быстро работают ? ни разу не встречал такого.

Добавлено через 2 минуты
а вообще спасибо попробую ваш вариант "cotseec"
0
Пишу на Delphi...иногда
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
26.03.2013, 00:36 4
в принципе тоже самое, что я написал, также выделение памяти, также добавление в список
про скорость ничего сказать не могу - не задумывался, хотя две операции против четырех при добавлении ... надо тики посчитать, думаю ваш вариант быстрее будет

Добавлено через 2 минуты
не доглядел, по сабжу....
утечка памяти при освобождении из-за стрингов в записи, используйте шортстринг (или PChar) и утечки не будет, в моем варианте также будет утечка
1
angstrom
26.03.2013, 00:38
  #5

Не по теме:


Что же ты в который раз прицепился к этим стрингам? Не будет никакой утечки - делай только правильно.

Пишу на Delphi...иногда
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
26.03.2013, 00:43 6
Цитата Сообщение от flatgad Посмотреть сообщение
И вот тут почему то память не освобождается.
Цитата Сообщение от angstrom Посмотреть сообщение
Что же ты в который раз прицепился к этим стрингам? Не будет никакой утечки - делай только правильно.
см. первый пост

если без деструктора объекта, то память освободится только после закрытия программы (это не .NET, где есть сборщик мусора), а если в процессе программы насоздавать кучу таких объектов и не до конца освободить - утечка может аукнуться, а деструктор предка (TObject) не освободит память, занятую в потомке, тип string, в свою очередь, является динамическим и размер памяти, необходимый для его выделения на этапе компиляции не известен, поэтому лучше использовать шортстринги, а если их размера мало, то PChar, с соответствующим освобождением памяти
1
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 735
26.03.2013, 13:34  [ТС] 7
Немного переработал. И вместо Tlist использовал TObjectlist получилось так :

Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type _TGPSData  = record
          Latitude  : Real;
        NSIndicator : char;
          Longitude : Real;
        EWIndicator : char;
           DateTime : pChar;
end;
// Клас без изменений 
...
//Создание списка 
list:=TObjectList.Create;
list.OwnsObjects:=true;
list.Capacity:=0;
...
//Добавление к списку 
 list.Add(TGPSRecordData.Create(gps));
...
// Очистка списка и его удаление
  list.clear;
  list.Capacity :=  0;
  list.Free;


Итого после смены string-а на Pchar и Char соответственно количество занимаемой памяти уменьшилось в 2-а раза. Очистка происходит без проблем. Но время на закрытие программы почему то увеличилось, правда память очищается без проблем.
Надеюсь этот вариант верный. Может у кого есть ещё варианты как использовать TObjectList или TList буду рад поглядеть.
Ещё вопрос встречал такой вариант типа делают класc наследник Item от Tobjectlist и с ним оперируют. http://www.base.vingrad.ru/view/3110-TObjectList, на сколько такой вариант харош? И стоит ли его применять?
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
26.03.2013, 14:21 8
Цитата Сообщение от cotseec Посмотреть сообщение
утечка памяти при освобождении из-за стрингов в записи, используйте шортстринг (или PChar) и утечки не будет, в моем варианте также будет утечка
Если используются классы, то из-за String утечки точно не будет. И переходить на ShortString здесь не надо, конечно. А вот в том коде, где используются GetMemory() и FreeMemory(), да ещё и CopyMemory() - это полный комплект, чтобы разрушить работу динамических типов. Вместо этого надо использовать New() и Dispose() - тогда утечек не будет. Потому что при вызове Dispose() для динамических типов выполняется финализация.
1
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 735
26.03.2013, 15:02  [ТС] 9
А вот такой вопрос я создал TobjectList далее добавляю, удаляю записи короче идет редактирование, а потом в какой то момент времени хочу глянуть сколько занимает места в памяти мой лист. Каким образом можно в сумме сразу получить количество байт ? ну если конечно это возможно.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
26.03.2013, 17:12 10
Цитата Сообщение от flatgad Посмотреть сообщение
Каким образом можно в сумме сразу получить количество байт ? ну если конечно это возможно.
Здесь надо использовать API менеджера памяти Delphi. Например, в каждый момент времени можно посмотреть сколько имеется выделенных (неосвобождённых) блоков и какой суммарный объём памяти эти блоки занимают. Неосвобождённые блоки - это все выделенные блоки. Среди них могут быть и потерянные и не потерянные.
Сколько выделено блоков и какой их суммарный размер в байтах:
Delphi
1
2
3
4
5
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Всего выделено блоков: ' + IntToStr(AllocMemCount)
    + #13#10'Суммарный размер блоков: ' + IntToStr(AllocMemSize));
end;
Соответственно, если в самом конце программы вызвать AllocMemCount() и если окажется, что эта функция вернёт ненулевое значение - значит имеются потерянные блоки.
Делается это таким образом.
1. Создаём модуль, например, с именем UnitMemTest:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
unit UnitTestMem;
 
interface
 
implementation
 
uses
  Windows;
 
initialization
 
finalization
 
begin
  //Проверка на неосвобождённые блоки.
  if AllocMemCount <> 0 then
    MessageBox(0, 'Есть неосвобождённые блоки', 'Отчёт',
      MB_OK + MB_ICONINFORMATION + MB_APPLMODAL)
  else
    MessageBox(0, 'Все блоки освобождены', 'Отчёт',
      MB_OK + MB_ICONINFORMATION + MB_APPLMODAL);
end;
 
end.
Здесь следует обратить внимание на то, что в коде, где выполняется вызов AllocMemCount() не используются никакие переменные - это условие обязательно должно выполняться. Это гарантирует, что сам этот код не потребует выделений памяти.
2. Следующий шаг - модуль UnitMemTest надо добавить в файл проекта *.dpr (например - Project1.dpr) и он должен быть записан первым в списке uses. Ещё раз обращу внимание - модуль должен быть указан именно в DPR файле и должен быть обязательно первым в списке uses:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
program Project1;
 
uses
  {Модуль UnitTestMem должен быть первым в списке uses.}
  UnitTestMem in 'UnitTestMem.pas',
  Forms,
  Unit1 in 'Unit1.pas' {Form1};
 
{$R *.res}
 
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
3. Теперь надо скомпилировать проект и запустить приложение. При выходе из приложения появится окно сообщения, которое известит - все ли блоки освобождены.
---
Можно и более сложные проверки делать. Для этого надо перехватить 2 функции менеджера памяти Delphi - запрос на выделение памяти и на освобождение памяти. И таким образом в самой программе вести учёт выделенных/освобождённых блоков.
Есть также специальное ПО для отслеживания утечек памяти в программах на Delphi.
---
Если есть желание узнать больше по этой теме, всем рекомендую серию материалов от GunsMoker-а: Блог GunSmoker-а: "Ищем утечки памяти".
Сам GunsMoker является одним из разработчиков в компании EurekaLog. Эта компания, занимается разработкой ПО для отладки приложений.
1
26.03.2013, 17:12
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.03.2013, 17:12
Помогаю со студенческими работами здесь

Тестер. Вопрос TList.
Собственно вопрос. Ошибка при добавлении элемента в древо вопросов. Не могу решить эту проблему....

Одновременное обращение к TList
Доброе время суток! Программе есть несколько таймеров которые одновременно работают они...

Tlist и считывание из Tedit
Доброго времени суток. Такая задача: нужно создать приложение, содержащее: список значений; поле...

Как создать TList?
Всем привет. Задача такая есть записи к примеру об успеваемости студентов. type Student =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Что такое HCL Notes и как с ним работать
InfoMaster 10.01.2025
HCL Notes (ранее известный как IBM Notes и Lotus Notes) представляет собой комплексную платформу для совместной работы и обмена информацией в корпоративной среде. Это многофункциональное решение,. . .
Как работать с Git из Windows и Visual Studio
InfoMaster 10.01.2025
Работа с Git в Windows Работа с Git в операционной системе Windows может быть осуществлена с помощью различных инструментов, каждый из которых обладает своими уникальными возможностями и. . .
Аналог оператора switch case в Python
InfoMaster 10.01.2025
Оператор switch case используется в программировании для выбора одного из нескольких вариантов исполнения кода. Однако в языке Python этот оператор отсутствует. Понимание аналогов switch case в. . .
Отличия абстрактного класса от интерфейса
InfoMaster 10.01.2025
В современной разработке программного обеспечения существуют два основных механизма реализации абстракции: абстрактные классы и интерфейсы. Эти инструменты, хотя и схожи в своей основной цели -. . .
Как работать в Git
InfoMaster 10.01.2025
Git — это одна из наиболее популярных систем контроля версий, которая активно используется разработчиками по всему миру. Она позволяет эффективно управлять изменениями в коде, координировать работу. . .
Реализация передвижения персонажа в Unity3d на C#
InfoMaster 10.01.2025
Реализация передвижения персонажа в Unity3D начинается с правильной настройки проекта. Этот этап критически важен для создания отзывчивого и плавного управления. Рассмотрим основные шаги для создания. . .
Docker: руководство для начинающих
InfoMaster 10.01.2025
В современном мире разработки программного обеспечения контейнеризация стала неотъемлемой частью процесса создания и развертывания приложений. Docker, как ведущая платформа контейнеризации, произвела. . .
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
Что такое NullReferenceEx­­­ception и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru