Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.01.10;
Скачать: CL | DM;

Вниз

Строку в объект   Найти похожие ветки 

 
sniknik ©   (2009-11-16 09:30) [80]

> Dispose(PMyRecord(ListView1.Items[i].Data));
PMyRecord(ListView1.Items[i].Data).Free;


 
Юрий Зотов ©   (2009-11-16 09:30) [81]

> kyn66 ©   (16.11.09 09:24) [78]

> Получается так, что если память выделена, то ее обязательно нужно
> чем-то заполнить.

Заполнять не обязательно. Обязательно другое - помнить адрес выделенного блока, чтобы потом можно было его освободить.

Похоже, Вы пока еще немного путаетесь. Есть АДРЕС выделенного блока, а есть СОДЕРЖИМОЕ этого блока. Это совершенно разные вещи. Адрес хранится в переменной типа "указатель", а содержимое хранится в самом блоке.


 
sniknik ©   (2009-11-16 09:33) [82]

а ну да, если у тебя там "дыры" то значит повторное использование тоже будет. значит
FreeAndNil(PMyRecord(ListView1.Items[i].Data));


 
Leonid Troyanovsky ©   (2009-11-16 09:47) [83]


> sniknik ©   (16.11.09 09:30) [80]

В начале было New.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2009-11-16 09:54) [84]


> kyn66 ©   (16.11.09 09:24) [78]

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

Здесь приведение лишнее, бо загромождает суть.

--
Regards, LVT.


 
kyn66 ©   (2009-11-16 10:03) [85]


> Заполнять не обязательно. Обязательно другое - помнить адрес
> выделенного блока, чтобы потом можно было его освободить.
>


Но в данном случае (заполнение в цикле) переменная инициализируется, получает/не получает значение, инициализируется на новый блок памяти. И имя переменной, связанной с конкретным блоком мы как таковое теряем. Т.е. к конкретному блоку по имени мы обратиться не сможем. Поэтому мы в цикле пробегаем по всем итемам и удаляем, если что то там есть

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


> Есть АДРЕС выделенного блока, а есть СОДЕРЖИМОЕ этого блока.
>  Это совершенно разные вещи. Адрес хранится в переменной
> типа "указатель", а содержимое хранится в самом блоке.

Не, с этим похоже разобрался уже.


 
Leonid Troyanovsky ©   (2009-11-16 10:11) [86]


> kyn66 ©   (16.11.09 10:03) [85]

> блок памяти. И имя переменной, связанной с конкретным блоком
> мы как таковое теряем. Т.е. к конкретному блоку по имени
> мы обратиться не сможем. Поэтому мы в цикле пробегаем по
> всем итемам и удаляем, если что то там есть

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

--
Regards, LVT.


 
kyn66 ©   (2009-11-16 10:26) [87]


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

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


 
Демо ©   (2009-11-16 11:33) [88]


> 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;


 
sniknik ©   (2009-11-16 11:35) [89]

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


 
kyn66 ©   (2009-11-16 13:05) [90]


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


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

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


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

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

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


 
Leonid Troyanovsky ©   (2009-11-16 13:26) [92]


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

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

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

--
Regards, LVT.


 
kyn66 ©   (2009-11-16 13:58) [93]


> А вот для удаления это важно, бо если компилятор не знает
> тип,то он и не вставит 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;


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

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

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


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


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

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

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

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


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

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

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


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


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

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

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

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


 
Leonid Troyanovsky ©   (2009-11-16 15:36) [97]


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

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

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

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2009-11-16 15:38) [98]


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

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

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

--
Regards, LVT.


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

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


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


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


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


 
kyn66 ©   (2009-11-16 15:57) [101]


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

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


 
kyn66 ©   (2009-11-16 15:59) [102]

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


 
Anatoly Podgoretsky ©   (2009-11-16 16:17) [103]

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

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


 
Leonid Troyanovsky ©   (2009-11-16 16:23) [104]


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

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

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

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

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

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

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

--
Regards, LVT.


 
kyn66 ©   (2009-11-16 16:31) [105]


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

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

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

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


 
kyn66 ©   (2009-11-16 16:39) [106]

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



Страницы: 1 2 3 вся ветка

Текущий архив: 2010.01.10;
Скачать: CL | DM;

Наверх




Память: 0.67 MB
Время: 0.02 c
11-1208790314
Jon
2008-04-21 19:05
2010.01.10
GIF encoding


2-1258544549
Oleg1963
2009-11-18 14:42
2010.01.10
Ищу родителей. Использование GetParent.


15-1257793401
xtest
2009-11-09 22:03
2010.01.10
Не могу добавить СЮДА свой вопрос.


8-1202287090
alex870
2008-02-06 11:38
2010.01.10
Скриншот содержимого Mediaplayer a


2-1258473755
6699
2009-11-17 19:02
2010.01.10
Файлы