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

Вниз

Ошибка в коде, который раньше работал.   Найти похожие ветки 

 
kyn66 ©   (2009-11-03 13:14) [0]

Уважаемые мастера. Помогите найти ошибку в коде, взятом из рабочей программы:
1) Наполняем st данными

procedure FormSt;
Var
 st : TStringList;
 Bitmap1 : TBitmap;
begin
 st := TStringList.Create;
 Bitmap1 := TBitmap.Create;
 ListBox1.Clear;
 for i := 1 to KolLotery do
  begin
    DM1.ImageList1.GetBitmap(32, Bitmap1);
    st.AddObject("первая запись", Bitmap1);
    st.AddObject("вторая запись", Bitmap1);
    st.AddObject("третья запись", Bitmap1);
  end;
 ListBox1.Items.AddStrings(st);
 st.Free;
 Bitmap1.Free;
end;


2) Отрисовываем ListBox с пиктограммами

procedure TMainFrm.ListBox1DrawItem(Control: TWinControl; Index: Integer;
 Rect: TRect; State: TOwnerDrawState);
Var
 Offset : Integer;
 Bitmap : TBitmap;
begin
 Offset := 0;
 with TCustomListBox(Control).Canvas do
  begin
    FillRect(Rect);
    Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
    if Bitmap <> nil then
     begin
       Bitmap.Transparent :=True;
       BrushCopy(Bounds(Rect.Left + 2, Rect.Top + 2, Bitmap.Width, Bitmap.Height),
                 Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height), clWhite);
       Offset := Bitmap.Width + 8;
     end;
    TextOut(Rect.Left + Offset, Rect.Top, Listbox1.Items[Index]);
  end;{With}
end;


Ошибка вылетает на "жирной" строке


 
Демо ©   (2009-11-03 13:22) [1]


> Ошибка вылетает на "жирной" строке


Что за ошибка? И что поменялось в окружении?


 
Сергей М. ©   (2009-11-03 13:23) [2]


> который раньше работал


Он и раньше не мог работать.
Ты ж Bitmap1 собственноручно убиваешь

см. Bitmap1.Free

а потом обращаешься к трупу за свойством Transparent

)


 
kyn66 ©   (2009-11-03 13:26) [3]

Ошибка стандартнонепонятнаяоткудавзятая Access Violation.

> Ты ж Bitmap1 собственноручно убиваешь


Так я же его убиваю Bitmap1, который используется в первой процедуре и нужен только для наполнения st данными. А ошибка вылетает во второй процедуре и используется там Binmap, без цифирей.


 
kyn66 ©   (2009-11-03 13:29) [4]


> Демо ©   (03.11.09 13:22) [1]
> > Ошибка вылетает на "жирной" строкеЧто за ошибка? И что
> поменялось в окружении?


Да собственно особо ничего. Раньше этот код работал в отдельной форме и объявлял я Bitmap в Interface формы, а убивал по Distroy формы. Вот и вся разница.


 
Сергей М. ©   (2009-11-03 13:29) [5]


> используется там Binmap, без цифирей.


И что ?
Цифирь эта  - всего лишь цифирь в идентификаторе лок.переменной.
Которая в строчке

Bitmap := TBitmap(ListBox1.Items.Objects[Index]);

получает значение, равное копии указателя на объект, который ты собственноручно убил в 1-й процедуре.


 
Игорь Шевченко ©   (2009-11-03 13:30) [6]


>     if Bitmap <> nil then


if Bitmap is TBitmap


 
Anatoly Podgoretsky ©   (2009-11-03 13:30) [7]

> kyn66  (03.11.2009 13:14:00)  [0]

Так и пишет "вылетаю на "жирной" строке"


 
Dennis I. Komarov ©   (2009-11-03 13:30) [8]


> Ошибка стандартнонепонятнаяоткудавзятая Access Violation.

очень даже всегда понятная: Был "Вася" и нет его...


 
Игорь Шевченко ©   (2009-11-03 13:30) [9]

Упс. Ты вообще соображаешь, что пишешь ? Марш за книжки


 
Сергей М. ©   (2009-11-03 13:31) [10]


> убивал по Distroy формы. Вот и вся разница


Т.е. убивал объект ты заведомо позже самого последнего обращения к нему.
А теперь ты сначала убил, а потом измываешься над трупом.
Вот и вся разница)


 
kyn66 ©   (2009-11-03 13:31) [11]


> а потом обращаешься к трупу за свойством Transparent


И тем более ошибка в блоке после проверки Bitmap на nil


 
Сергей М. ©   (2009-11-03 13:32) [12]


> в коде, который раньше работал


Раньше был другой код.
Потому и работал.


 
Dennis I. Komarov ©   (2009-11-03 13:32) [13]


> И тем более ошибка в блоке после проверки Bitmap на nil

А с чего ты взял, что там nil?


 
Сергей М. ©   (2009-11-03 13:34) [14]


> ошибка в блоке после проверки Bitmap на nil


А почему бы ей не быть не-nil ?
Ты же записал не-nil, вот она и прошла проверку.
А объект ты убил.
А ссылка на него осталась.


 
kyn66 ©   (2009-11-03 13:34) [15]


> получает значение, равное копии указателя на объект, который
> ты собственноручно убил в 1-й процедуре.


Bitmap локально объявлен во второй процедуре и с успехом инициализируется там же

Bitmap := TBitmap(ListBox1.Items.Objects[Index]);


Терзают смутные сомнения по поводу корректной отработки st.AddObject("вторая запись", Bitmap1)...


 
Сергей М. ©   (2009-11-03 13:35) [16]


> и с успехом инициализируется там же
>


мусором !

Объекта-то нет, ты уничтожил его до этого !


 
Сергей М. ©   (2009-11-03 13:36) [17]


> смутные сомнения по поводу корректной отработки st.AddObject("вторая
> запись", Bitmap1)


Не терзайся, он работает абсолютно корректно - копирует строки и ассоциированные с ними ссылки.


 
clickmaker ©   (2009-11-03 13:36) [18]

> Bitmap локально объявлен во второй процедуре и с успехом
> инициализируется там же
>
> Bitmap := TBitmap(ListBox1.Items.Objects[Index]);

это не инициализация. Это присваивание значения указателя, который указывает уже на труп


 
kyn66 ©   (2009-11-03 13:39) [19]


> Сергей М. ©   (03.11.09 13:34) [14]


Я дико извеняюсь, но закомментировал "убийство" Bitmap1 и все пошло нормально. Я подумал что он уже не нужен, поскольку Listbox1 уже наполнен данными... ListBox1.Items.AddStrings(st);


 
Сергей М. ©   (2009-11-03 13:41) [20]


> акомментировал "убийство" Bitmap1 и все пошло нормально


Теперь тебя ждут другие грабли - утечка памяти


 
Dennis I. Komarov ©   (2009-11-03 13:43) [21]


> Сергей М. ©   (03.11.09 13:41) [20]

Фигня то какая... Разве ее мало? Разве нас это заставит буквари читать?


 
kyn66 ©   (2009-11-03 13:44) [22]

Просто procedure FormSt; может повторяться несколько раз, поэтому и решил что нужно удалять ненужные объекты, так как в этой процедуре Bitmap1 создается заново
Bitmap1 := TBitmap.Create;


 
kyn66 ©   (2009-11-03 13:45) [23]



> Сергей М. ©   (03.11.09 13:41) [20]


> Теперь тебя ждут другие грабли - утечка памяти


:) Сообщение появилось пока я про это и пмсал [22].


 
clickmaker ©   (2009-11-03 13:47) [24]

> Я подумал что он уже не нужен, поскольку Listbox1 уже наполнен
> данными

AddObject не копирует объект.
и почему бы не вызвать DM1.ImageList1.GetBitmap(32, Bitmap1); один раз?
а при закрытии программы убить глобальный объект Bitmap1


 
kyn66 ©   (2009-11-03 13:48) [25]

2Сергей М.

Как посоветует мастер поступить в такой ситуации? Чтобы и волки были сыты......


 
kyn66 ©   (2009-11-03 13:51) [26]


> и почему бы не вызвать DM1.ImageList1.GetBitmap(32, Bitmap1);
>  один раз?а при закрытии программы убить глобальный объект
> Bitmap1


Согласен, так можно и сделать. У Bitmap1 небольшая смысловая нагрузка, в плане просто картинку передать и все. Можно его отдельно создать и главное потом не забыть его удалить по завершении.


 
Сергей М. ©   (2009-11-03 13:51) [27]

Вернись к варианту, котоый был раньше ("работал").
И вынеси GetBitmap из тела цикла.


 
Сергей М. ©   (2009-11-03 13:53) [28]


> главное потом не забыть его удалить по завершении


Можешь даже и не удалять - система не обеднеет, это для нее не потеря.


 
Демо ©   (2009-11-03 14:06) [29]


> Сергей М. ©   (03.11.09 13:53) [28]
>
> > главное потом не забыть его удалить по завершении
>
>
> Можешь даже и не удалять - система не обеднеет, это для
> нее не потеря.
>
>

Ж-))


 
kyn66 ©   (2009-11-03 14:45) [30]


> Сергей М. ©   (03.11.09 13:51) [27]
> Вернись к варианту, котоый был раньше ("работал").И вынеси
> GetBitmap из тела цикла.


Все понял! Спасибо!
Тема закрыта.


 
kyn66 ©   (2009-11-03 15:59) [31]

2Сергей М. ©

Я извеняюсь, не вовремя объявил о закрытии темы. Хотел задать еще один вопрос , а чем от Bitmap1 отличается st. При уничтожении Bitmap1 возникает ошибка(правильная), а при уничтожении st ошибки нет? Чем они отличаются?

...
 st.AddObject("третья запись", Bitmap1);
 end;
ListBox1.Items.AddStrings(st);
st.Free;
Bitmap1.Free;
end;


[0]

Спецом решил уничтожить st и все работает...


 
clickmaker ©   (2009-11-03 16:16) [32]

> чем от Bitmap1 отличается st

тем, что AddObject НЕ копирует объект, а AddStrings - копирует строки в листбокс


 
Германн ©   (2009-11-03 16:19) [33]


> Я извеняюсь, не вовремя объявил о закрытии темы. Хотел задать
> еще один вопрос , а чем от Bitmap1 отличается st. При уничтожении
> Bitmap1 возникает ошибка(правильная), а при уничтожении
> st ошибки нет? Чем они отличаются?
>

Они ничем не отличаются друг от друга. Обе - локальные переменные процедуры FormSt.
А отличие указано в

> clickmaker ©   (03.11.09 13:47) [24]
>
> > Я подумал что он уже не нужен, поскольку Listbox1 уже
> наполнен
> > данными
>
> AddObject не копирует объект.


 
kyn66 ©   (2009-11-03 16:20) [34]


> а AddStrings - копирует строки в листбокс


Но в данном случае копируются строки, содержащие указатель на объект, который нельзя уничтожать (Bitmap1). Как это увязывается вместе?


 
clickmaker ©   (2009-11-03 16:40) [35]

> Как это увязывается вместе?

так, что строки - управляемый объект. Для них VCL выделяет память и следит за ссылками. А про абстрактный объект метод ничего не знает. Там может быть и record и просто число типа int


 
Германн ©   (2009-11-03 17:43) [36]


> Но в данном случае копируются строки, содержащие указатель
> на объект, который нельзя уничтожать (Bitmap1). Как это
> увязывается вместе?

Если подумать, то этот вопрос сам в себе содержит и точный ответ и ошибку в понимании основ. :)


 
kyn66 ©   (2009-11-03 17:50) [37]


> clickmaker ©   (03.11.09 16:40) [35]


Спасибо.


 
kyn66 ©   (2009-11-05 10:50) [38]

Уважаемые мастера! Прошу разъяснить еще раз, ну не могу понять связи.... См.[0]. Какая связь между двумя переменными Bitmap1(объявлена в первом блоке кода) и Bitmap(объявлена во втором блоке). Все сделал как говорили, все работает, но хочу глубже разобраться. В сети нашел почти аналогичный пример http://demi-s.narod.ru/components/034.html Тм тоже ListBox получает картинки из объекта. Так вот, в блоке примераListBox1DrawItem тоже объявлена как и у меня переменная Bitmap и после отрисовки она уничтожается. В своей программе я объявил Bitmap1 : TBitmap глобально и уничтожаю ее после деактивации основной формы. Но стоит мне в своем втором блоке уничтожить переменную Bitmap после отрисовки ListBox, при закрытии программы вылетает ошибка Access violation по отношению  к глобальнообъявленной переменной Bitmap1

procedure TMainFrm.FormDestroy(Sender: TObject);
begin
 Bitmap1.Free;
end;

Разъясните спокойно, без эмоций, какая между ними связь? И почему при уничтожении локально объявленной Bitmap теряется связь с глобально объявленной Bitmap1. Спасибо.



 
Сергей М. ©   (2009-11-05 10:54) [39]


> Какая связь между двумя переменными Bitmap1(объявлена в
> первом блоке кода) и Bitmap(объявлена во втором блоке)


Обе переменные содержат значение, являющее собой указатель на один и тот же объект.


 
RWolf ©   (2009-11-05 10:58) [40]

в Дельфи Bitmap:TBitmap — на самом деле указатель на объект.
Строкой DM1.ImageList1.GetBitmap(32, Bitmap1); ты присваиваешь ему адрес реально существующего объекта, который хранится в ImageList1. Кроме того, этим же объектом пользуется процедура ListBox1DrawItem. Кода ты выполняешь Bitmap.Free, объект уничтожается, и при обращеннии по его адресу из другого места программы имеем глюк.



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

Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.008 c
6-1209028510
ivanov
2008-04-24 13:15
2009.12.20
3агрузить страницу с подменой своего стиля


15-1256122591
oldman
2009-10-21 14:56
2009.12.20
Сегодня 91 год Александу Аркадьевичу Гинзбургу


15-1255765672
Virgo_Style
2009-10-17 11:47
2009.12.20
Раздача слонов - Paragon Partition Manager 9.5 Professional


15-1256014607
@!!ex
2009-10-20 08:56
2009.12.20
Как сделать движущуюся линию на Flash?


1-1229610779
Denis__
2008-12-18 17:32
2009.12.20
Многочлены





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский