Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.01.10;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.66 MB
Время: 0.01 c
15-1257526923
Avant Browsr
2009-11-06 20:02
2010.01.10
Где хранятся "Избранное" и "Журнал"?


15-1257712925
POOP
2009-11-08 23:42
2010.01.10
При отражении длина световой волны меняется?


15-1257541254
Игорь Шевченко
2009-11-07 00:00
2010.01.10
Дмитрий Заварзин aka Думкин, с днем рождения!


11-1208790314
Jon
2008-04-21 19:05
2010.01.10
GIF encoding


15-1257524073
trxnet
2009-11-06 19:14
2010.01.10
Количество треугольников в массиве





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский