Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];
Внизосвобождение памяти Найти похожие ветки
← →
del (2004-01-08 07:06) [0]Здравствуйте !
Написал класс TTreeManager, управляющий узлами TTreeView. TTreeView передается этому классу как значение свойства tm.TreeView := TreeView (tm is type TTreeManager).
Для хранения свойств узла используется класс TNodeData, хранящийся в node.Data (node is type TTreeNode).
В destructor TTreeManager.Destroy; выполняется освобождение памяти всех созданных классов как (nodeData as TNodeData).Free.
При закрытии главной формы возникает ошибка обращения к памяти:
"Accsess violation at address 00451837 ... . Read of address 00000004." Ошибка возникает при чистке узлов TreeView.
Если в в обработчике события FormDestroy главной формы поставить tm.Free, ошибка не возникает.
Владелец TreeView и tm - главная форма.
Вопрос вот в чём: этот tm type TTreeManager является кандидатом в компонент, и я боюсь, что возникнет такая же ошибка. Похоже, я пытаюсь обратиться к освобожденной памяти.
Как в этом случае корректно освобождать память ?
← →
Broot (2004-01-08 08:28) [1]Память освобождай там, где ты выделял под нее место. Т.е. если ты в свой менеджер передаешь ссылки на уже существующие узлы, то не надо их в этом менеджере удалять. Обычно за удаление объекта отвечает другой объект его создавший. Опиши точнее в каком месте программы создаются твои объекты.
← →
Anatoly Podgoretsky (2004-01-08 09:08) [2]У тебя не один вопрос, а три
1. Не бойся будет
2. освобождение не имеет отношения к обращению, жта проблема будет и в случае отсутствия своего менеджера, не обращайся
3. освобождать надо корректно.
Но у тебя проблема не освобождения, а работа с несуществующими уже объектами (не принадлежащей тебе памятью).
← →
del (2004-01-08 09:49) [3]2 Broot
В TreeManager я устанавливаю свойство TTreeView, сам объект TTreeView создан в главной форме. TreeManager заполняет его узлами. TTreeView не удаляется в TreeManager, - в его деструкторе удаляются (.Free) только данные узлов. И именно при удалении данных узлов формируется error. Может быть, при закрытии главной формы вначале удаляется TTreeView, а затем TreeManager, - тогда понятна причина error. А как управлять порядком выполнения .Free в главной форме ?
Anatoly Podgoretsky !
Да, у меня получается "работа с несуществующими уже объектами (не принадлежащей тебе памятью)." А как этого избежать ? Я ведь дожен освободить память от всех созданных TNodeData, - они создаются в TreeManager.
О ! оказывается в коде TNodeData образован от Class, а Class не имеет свойства Owner. Может быть это - причина ? щас проверю.
← →
KSergey (2004-01-08 11:24) [4]А может просто наследника TreeView состряпать? Может это будет проще, чем париться с "левым" менеджером и уведомлениями когда кто создался и кто когда погиб?
← →
del (2004-01-08 12:20) [5]KSergey !
Хорошая мысль ! А чой-то я, действительно, парюсь ?
ну, спасибо. так и сделаю.
Вы, KSergey, конечно, молоток, но по сути вопроса: мне кажется
дело в том, что порядок выполнения .Free в Delphi неопределен и для исходной ситуации за этим придется следить, или нет ?
← →
Тимохов (2004-01-08 12:22) [6]"что порядок выполнения .Free в Delphi неопределен"
Классная фраза, чессо слово!
Интересно услышать, что этим автор хотел сказать.
← →
klyonov (2004-01-08 12:48) [7]TTreeView.Items освобождаются автоматом при разрушении TreeView, по-моему.
может тебе их вообще не надо разрушать в своем менеджере?
← →
Erik (2004-01-08 12:53) [8]Если действительно нехочеш парится, то ненадо избретаь велосипед! Все уже до тебя написано, очень многоими изобретателями. :)
Можно сделть еще проще неработать с выделением, освобождением памати самому. Пусть стандартные механизмы поработают. Я например просто создал масив а в дата запоминал его индекс. Поскольку это переменая то она сама уничтожается при разрушении класса(например формы).
Есть и другой путь, берем TVirtualStringTree и вперед. Там надо только указать размер пользовательских данных. Он сам все выделит и освободит. Мне очень понравился компонент, на него вобще можно весь интерфейс программы перевести + редактирование.
← →
Тимохов (2004-01-08 12:55) [9]Erik © (08.01.04 12:53) [8]
Я сам хотел написать совет с запоминанем индекса. Но подумал, что сразу возникнут вопросы, что делать если дерево активно меняеятся - идет вставка, удаление листков. Метод то хорош, но имхо для определенных целей.
← →
Erik (2004-01-08 13:28) [10]Все решаемо, например делаем
TState = (stNone, stDelete, stInsert, stModify, stError, stInit);
RSeadmed = record
ID, ParentID: Integer;
TyypID: Integer;
LepAdrID: Integer;
Nimetus: ShortString;
State: TState;
// Node: PVirtualNode; - это для TVirtualStringTree
end;
PointSead = ^RSeadmed;
TSeadmed = array of RSeadmed;
TPSeadmed = ^TSeadmed;
В State ставим stDelete при удалении ветки, со вставкой проблем и так нет если масив динамический. А после переодически пакуем масив Move(...). Разумеется с переопределением индексов в Data.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.009 c