![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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. При необходимости храни элементы в связном списке.