klen |
Отправлено: 27.03.2004, 11:17 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Здравствуйте все.
Подскажите пожалуйста, как имея указатель TComponent* (не равный нулю) определить жив ли еще объект на который он указывает или его уже разрушили оператором delete.
Есть вариант вызвать любую нестатическую функцию класса, это приведет к исключению в случаее если он мертвый, но не хочется через исключения это делать. |
|
Георгий |
Отправлено: 27.03.2004, 12:13 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
попробуй использовать умные указатели (smart pointers) — в BCB класс называется auto_ptr |
|
klen |
Отправлено: 27.03.2004, 15:09 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Век живи век учись, первый раз от таком слышу.
Прикольно, даже хелп есть.
Спасибо. |
|
Asher |
Отправлено: 29.03.2004, 08:34 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
Ты с auto_ptr будь по-аккуратнее. Они там "прикольно" копируются, особенное если не дай бог это указатель приведенный к предку.
Потеря информации гарантированна. Именно по этой причине с ними категорически нельзя испльзовать STL'евские контейнеры.
|
|
olegenty |
Отправлено: 29.03.2004, 10:56 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
если уверен в том, что по указателю был экземпляр вполне конкретного класса, то можешь сделать следующее:
[CODE]
if (ТвойКласс *test = dynamic_cast<ТвойКласс*>(ТвойУказатель))
{
делай, всё, что хочешь...;
} else
{
raise Exception("Указатель успешно скончался/The pointer is succesfully dead");
}
|
|
Deem |
Отправлено: 29.03.2004, 14:59 |
|
Мастер участка
Группа: Участник
Сообщений: 327
|
Попробуй обратиться к методу или свойству объекта в try {}
А дальше catch(...) {Pointer = NULL;}
А вобще-то даже delete пинтер никогда не обнуляет. Следи за указателями, и обнуляй при удалении объекта. А все элементы VCL не оставляют указателей при удалении родственников (не встречал).
|
|
klen |
Отправлено: 29.03.2004, 23:37 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Мужики, по эксепшену то понятно, обьекта нет значит ошибка нарушения зашиты памяти будет, а как без эксепшенов обойтись.
Вопрос удобства на самом деле — в программе то раьотать будет, а вот пока ее пишешь замучишься на кнопки OK давит при каждом эксепшене. |
|
Asher |
Отправлено: 30.03.2004, 08:27 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
Если разрушаешь сам — то присваивай указателю NULL, а если делаешь дополнительные указатели на этот объект — то делай указатель на этот указатель. Тогда обнулив базовый указатель существование объекта можно проверить одиночным разименованием с сравнением на NULL.
Что-то типа этого
CODE |
int i1 = 10;
int *pi1;
int **ppi1;
pi1 = &i1;
ppi1 = &pi1;
*pi1 = 11;
pi1 = NULL;
if (*ppi1 != NULL)
**ppi1 = 12;
|
|
|
klen |
Отправлено: 30.03.2004, 11:58 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Так вся проблема в том что не я разрушаю, это принципиальная особенность моей задачи — объект разделяймый, а те кто к нему имеют доступ не должны иметь между собой никакого интерфейса. Задача такая однако |
|
Asher |
Отправлено: 30.03.2004, 12:09 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Ну дык...
Удаляется же он не просто так, а в ответ на какие-то действия. Там и обнулять самому.
А все остальные обращающиеся — имеют к нему доступ не через указатель на объект, а через указатель на указатель.
Или они имеют к нему доступ без указателя?
|
|
klen |
Отправлено: 30.03.2004, 12:21 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Да вот эти самые действия в другой биьлиотек и писаной савсем не мной я мало чего переделать могу.
Ладно, хватит, переведем в другу плоскость:
Чисто академический вопрос :
Имеем значения адресса памяти 0xXXXXXXXXX , задача — установить : является ли эта ячейка памяти указателем на обьект класса насследованного от TXyz или не является таковым. Все. |
|
olegenty |
Отправлено: 30.03.2004, 13:18 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
вот как раз так, как я выше писал:
CODE |
if (TXyz *Test = dynamic_cast<TXyz*>(Твой адрес))
{
ShowMessage("Является наследником TXyz");
// продолжаетм разбор
if (TXyzНаследник *TestНаследник = dynamic_cast<TXyzНаследник*>(Test))
{
...
}
}
|
|
|
Asher |
Отправлено: 30.03.2004, 14:07 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Конечно. Только все прекрасно приведется, если никто память не по-портил
Вставь это в пустой проект
CODE |
TForm* l_pForm = new TForm(this);//
delete l_pForm;//
TForm* l_pTest = dynamic_cast<TForm*>(l_pForm);//Попытка приведения
if (l_pTest != NULL){
int i1 = 0;//
}
|
Ы?
|
|
klen |
Отправлено: 30.03.2004, 16:24 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Мужики, проблема решена.
Так как по указателю нет ничего dynamic_cast обязательно к эксепшену приведет, ему RTTI обиекта нужно, а если обьекта не то, и RTTI нет со всеми вытекающими, я о об этом подробно написал http://www.bcbdev.ru/phpbb/viewtopic.php?t=1024
Проблема решается гениально и просто (по моему мнению) — Api дает функции менеджера памяти для выяснения принадлежит ли регион адресного пространства процессу или нет и если принадлежит то что с ним может желать процесс, если обьект разрушен то регион из кучи забирает система и в него нельзя ни писать ни читать ни ваполнять в нем код!
Для тех кто догнал постановку задачи и для которых она является актуальной отсылаю к справке по Memory Management Functions
смотри описание функций
IsBadCodePtr
IsBadHugeReadPtr
IsBadHugeWritePtr
IsBadReadPtr
IsBadStringPtr
IsBadWritePtr
Спасибо всем за участие.
--- может так статся что в регионен памяти уже другой объект, тогда.....---
Отредактировано klen — 30/03/2004, 17:27 |
|