Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Строку в объект [D7, XP]


Страницы:   1 2 3 4 5 6

kyn66 ©   (2009-11-12 16:11:00) 

Подскажите, каким способом можно строку вставить в объект , ну например ComboBox ? Нужно к примеру просканировать текущий каталог диска, найденные файлы записать в Combobox, а полный путь к файлу сохранить в объекте. Помню со строками есть проблемы при сохранении в объект. Есть вот такой вариант

....
var
 PS: PString;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
 new(PS);
 PS^ := 'Hello world 1';
 ComboBox1.Items.AddObject('Item1', TObject(PS));
 PS^ := 'Hello world 2';
 ComboBox1.Items.AddObject('Item2', TObject(PS));
 PS^ := 'Hello world 3';
 ComboBox1.Items.AddObject('Item3', TObject(PS));
...

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Dispose(PS);
end;


При доступе к объекту

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ShowMessage(PString(Combobox1.Items.Objects[0])^); //Hello world 1
end;


возникает ошибка (AV)


kyn66   (2009-11-16 16:39:00) [1]

Да, прверил, вместо ShowMessage(IntToStr(AllocMemSize));заменил на Application.MessageBox(PChar(IntToStr(AllocMemSize)), PChar(''), MB_OK + MB_ICONASTERISK);и все стало на свои места. 12252=12252(до и после)


kyn66   (2009-11-16 16:31:00) [2]


> Как же - без разницы :)Измерять надо после первого ShowMessage.

Я так и измерял. После первого - 12252, после второго и последующего - 12284, даже не используя объекты(new/dispose)

> Ну, например, класс окна регистрируют не на один показ.

Вот может за счет этого и есть разница. И ею можно принебречь, я имею ввиду судя по данному тесту. Кстати, по совету [94] подключил FastMM, все настроил как показано в http://timokhov.blogspot.com/2007/03/delphi-2007-iii-fastmm.html. Инициализировал указатели и спецом их не уничтожая закрыл форму. Чегость утечки FastMM не показал. Хм, по консольному приложению из примера на сайте показывал.


Leonid Troyanovsky   (2009-11-16 16:23:00) [3]


> kyn66 ©   (16.11.09 15:57) [101]

> >Попробуй повторить создание-разрушение дважды(без уничтожения
> >формы).

> Без разницы.

Как же - без разницы :)
Измерять надо после первого ShowMessage.

> kyn66 ©   (16.11.09 15:59) [102]

> Получается что ShowMessage внес изменения в память и при
> закрытии не подчистил за собой.

Ну, например, класс окна регистрируют не на один показ.

--
Regards, LVT.


Anatoly Podgoretsky   (2009-11-16 16:17:00) [4]

> kyn66  (16.11.2009 15:57:41)  [101]

Вот и эта ветка уже за 100 постов.


kyn66   (2009-11-16 15:59:00) [5]

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


kyn66   (2009-11-16 15:57:00) [6]


> Leonid Troyanovsky ©   (16.11.09 15:36) [97]
>Попробуй повторить создание-разрушение дважды(без уничтожения >формы).

Без разницы. Как толькл открылась форма 12252. По пять раз создавал уничтожал - 12284. Однако заметил вот где. Открылась форма - смотрю память - 12252. Закрываю ShowMessage. Не создавая и не уничтожая объектов повторяю просмотр памяти - опс - 12284, еще и еще и еще смотрю память(объекты не трогаем) - 12284.


Дмитрий Белькевич   (2009-11-16 15:41:00) [7]


> Попробуй повторить создание-разрушение дважды(без уничтожения
> формы).


А лучше без формы и, вообще, без VCL'а и без окон (в консольном приложении). VCL и Winapi много неявнях телодвижений с памятью делают.


Дмитрий Белькевич   (2009-11-16 15:39:00) [8]

Сразу же смотри FullDebugMode. Это дополнительно укажет двойное освобождение переменных.


Leonid Troyanovsky   (2009-11-16 15:38:00) [9]


> Leonid Troyanovsky ©   (16.11.09 15:36) [97]

> память для регистрации класса.

В смысле: для регистрации класса окна.

--
Regards, LVT.


Leonid Troyanovsky   (2009-11-16 15:36:00) [10]


> kyn66 ©   (16.11.09 13:58) [93]

> цикл и опять проверяю память - 14000, уничтожаю объекты
> с приведением - 12284. Хотя память не вернулась к числу
> начальному 12252(нужно разобраться почему).

Возможно, что, например, первый показ ShowMessage требует
память для регистрации класса.
Попробуй повторить создание-разрушение дважды
(без уничтожения формы).

--
Regards, LVT.


kyn66   (2009-11-16 15:17:00) [11]


> typeinfo, я так думаю, отдаётся разный и финализация происходит
> неверно.

Да действительно, Leonid Troyanovsky ©   (16.11.09 13:26) [92] уже это подчеркнул.

> В дополнение к экспериментам рекомендую использовать FastMM.
>  Она сразу же утечки покажет.

Да, спасибо, сечас буду почитать про него.


Дмитрий Белькевич   (2009-11-16 15:12:00) [12]

>Хотя память не вернулась к числу начальному 12252(нужно разобраться почему)

Опять же - фрагментацию памяти не стоит забывать. Фрагментация памяти, кстати, одна из причин, по которой я бы не рекомендовал использовать New/Dispose. Если уж очень хочется извращаться - делай динамический массив записей и единомоментно (или 'чанками' по тысяче, если заранее неизвестен размер) устанавливай его размер. Это сильно уменьшит фрагментацию памяти и ускорит работу, иногда на порядок.


Дмитрий Белькевич   (2009-11-16 14:57:00) [13]

>Хотя память не вернулась к числу начальному 12252(нужно разобраться почему)

Кроме твоих записей может (и будет) создаваться разный самоуничтожаемый 'мусор'.


> Однако, когда я делаю уничтожение без приведения, память
> - 12460. Тоже не возвращается к начальному 12252


Смотри сырцы - найдёшь много интересного:

procedure _Dispose(p: Pointer; typeInfo: Pointer);
begin
 _Finalize(p, typeinfo);
 FreeMem(p);
end;

typeinfo, я так думаю, отдаётся разный и финализация происходит неверно.

В дополнение к экспериментам рекомендую использовать FastMM. Она сразу же утечки покажет.


kyn66   (2009-11-16 13:58:00) [14]


> А вот для удаления это важно, бо если компилятор не знает
> тип,то он и не вставит Finalize для очистки, скажем, строк.


Ага... решил мастера поймать... :) Дело в том, что я проверил еще одну ситуацию на коде из трех кнопок.
1) Запускает цикл с инициализацией переменной указателя, присваивает значения;
2) Удаление объектов:
3) Просто показывает память ShowMessage(IntToStr(AllocMemSize));

Так вот. Запускаю форму, проверяю память - 12252. Запускаю цикл и опять проверяю память - 14000, уничтожаю объекты с приведением - 12284. Хотя память не вернулась к числу начальному 12252(нужно разобраться почему). Однако, когда я делаю уничтожение без приведения, память - 12460. Тоже не возвращается к начальному 12252

procedure TForm1.Button2Click(Sender: TObject);
var
 i:integer;
begin
 for i:=0 to ListView1.Items.Count-1 do
   Dispose({PMyRecord}(ListView1.Items[i].Data));
 ListView1.Clear;
end;


Leonid Troyanovsky   (2009-11-16 13:26:00) [15]


> kyn66 ©   (16.11.09 13:09) [91]

> и удаление можно выполнять без приведения?

А вот для удаления это важно, бо если компилятор не знает тип,
то он и не вставит Finalize для очистки, скажем, строк.

--
Regards, LVT.


kyn66   (2009-11-16 13:09:00) [16]

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

if ListView1.Items[i].Data<> nil then
 Dispose(ListView1.Items[i].Data);


kyn66   (2009-11-16 13:05:00) [17]


> Leonid Troyanovsky ©   (16.11.09 09:54) [84]
> if PMyRecord(ListView1.Items[i].Data)) <> nil
>Здесь приведение лишнее, бо загромождает суть.


Т.е. в данном случае важнее узнать есть ли там что либо для уничтожения и не важно какого типа?

if (ListView1.Items[i].Data) <> nil


sniknik   (2009-11-16 11:35:00) [18]

> В начале было New.
догадался... тема сбила "Строку в объект", как то больше в другим ассоциируется.


Демо   (2009-11-16 11:33:00) [19]


> for i:=0 to ListView1.Items.Count-1 do
>  Dispose(PMyRecord(ListView1.Items[i].Data));
> end;


Просто проверь - ссылается ли куда-то ListView1.Items[i].Data:

for i:=0 to ListView1.Items.Count-1 do
begin
  if ListView1.Items[i].Data<> nil then Dispose(PMyRecord(ListView1.Items[i].Data));
end;


kyn66   (2009-11-16 10:26:00) [20]


> У блока нет имени, а есть адрес, скажем, его начала,

Пардонс, не так выразился. Конечно же адрес(имелось ввиду имя переменной для конкретнокго адреса блока памяти). Информации предостаточно. Большое спасибо всем мастерам за разъяснения и толерантность.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо