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

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

Node.Data - указатель на структуру... [D6, WinXP]


01 ©   (2005-03-02 07:09:00) 

Создал структуру:

type
 Trec = record
  i: Integer;
 end;

Глобалки:
 dData: array of Trec;
 dCount:integer = 0;

Есть TreeView. И при добавлении в него:

Node:=TreeView1.Items.AddChild(Node,Q.FieldByName('Answers').AsString);
SetLength(dData,dCount+1);
Node.Data:=@dData[dCount];
Inc(dCount);

И есть:

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
 Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin  
if Trec(Node.Data^).i=5 then
Sender.Canvas.Font.Color:= clBlack else Sender.Canvas.Font.Color:= clGray;
end;

При рисовании вылетает с Access violation..
Кто подскажет, в чем дело?


01   (2005-03-02 08:28:00) [1]


> Когда она возникнет вспомни мои слова.

Ну что же так трагично! )


> Использование:
>  Q.Locate('Id', PRec(node.Data)^.i, [])

Хм, об ентом не упоминалось.. Но мысль верно поймана.

> Ecли кроме целого в record-е ничего нет, то ещё проще, ничего
> выделять и освобождать не надо, просто используеи node.Data
> для хранения целого

Там еще много чего.. помимо целого.. Просто не стал проблему усложнять..


> КаПиБаРа ©   (02.03.05 07:47) [3]


> ЮЮ ©   (02.03.05 08:05) [4]

Благодарю за ответы. Прозрел! )


ЮЮ   (2005-03-02 08:07:00) [2]

Последняя строчка, естественно, должна быть просто
Q.Locate('Id', Integer(node.Data), [])


ЮЮ   (2005-03-02 08:05:00) [3]

>то у меня ничто бы не работало бы.. Но ссылки сохраняются

А ты сравни Node.Data и @dData[dCount] через некрторое время!
А работает, вероятно, потому, что освобожденная память ничем ещё не была занята и , естественно, по адресу Node.Data всё ещё лежат корректные данные. Но это не вечно :)

type
TRec = record
 i: Integer;
end;
PRec = ^TRec;

выделение памяти:
var
 data: PRec;
...
 New(data);
 Data^.i :=Q.FieldByName('Id').AsInteger;
 node := TreeView1.Items.AddChild Object(node, Q.FieldByName('Answers').AsString, data);

Использование:
 Q.Locate('Id', PRec(node.Data)^.i, [])

Освобождение:
 в обра,отчике TreeView.OnDeletion

var
 data: PRec;
...
 data := PRec(node.Data);
 Dispose(data);

Ecли кроме целого в record-е ничего нет, то ещё проще, ничего выделять и освобождать не надо, просто используеи node.Data для хранения целого:  

node := TreeView1.Items.AddChild Object(node, Q.FieldByName('Answers').AsString, TObject(Q.FieldByName('Id').AsInteger));
...
Q.Locate('Id', Integer(node.Data)^.i, [])


КаПиБаРа   (2005-03-02 07:47:00) [4]

01   (02.03.05 7:37) [2]
Естественно память ранее занимаемая массивом специально не затирается. Она помечается как свободная и со временем может быть выделена под другие нужды и соответственно в нее будут внесены другие данные. А пока по этим адресам хранится "призрак" массива. И все обращения за исключением последнего элемента идут к этому "призраку". Причем таких "призраков" ты создаешь множество.

В будущем это может вызвать трудноуловимую ошибку. Когда она возникнет вспомни мои слова.


01   (2005-03-02 07:37:00) [5]


> Естественно все указатели на адреса элементов массива становятся
> недействительными.

Я ошибся в другом месте. Сейчас все работает.
Но если б было так как ты сказал, то у меня ничто бы не работало бы.. Но ссылки сохраняются.

Но тем не менее, это что, очень не корректно????
И как в моемслучае "освобождать ранее занятое"?


КаПиБаРа   (2005-03-02 07:21:00) [6]

При увеличении динамического массива под него выделяется новый блок памяти и данные копируются в него. Естественно все указатели на адреса элементов массива становятся недействительными.
Создавай/удаляй записи с помощью New/Dispose. При необходимости храни элементы в связном списке.


Наверх

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