![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Gitulyar |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 31.1.2007 Репутация: нет Всего: нет |
Есть ненулевой указатель. Как определить объект на который он ссылается уже создан и можно ли использовать его поля и методы или сначало надо создать этот объект?
|
|||
|
||||
| Kuvaldis |
|
|||
![]() механик-вредитель ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1189 Регистрация: 16.6.2006 Где: Минск Репутация: 11 Всего: 61 |
Gitulyar,
Вообще-то лучше в конструкторе все указатели сразу инициализировать, чтобы ты ТОЧНО знал, что если указатель ненулевой, то память для него выделена, и наоборот -------------------- Помни - когда ты спишь, враг не дремлет Спи чаще и дольше, изматывай врага бессоницей |
|||
|
||||
| SerpentVV |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 27.11.2006 Где: Астрахань Репутация: 1 Всего: 1 |
Чисто по указателю никак не определить, куда он указывает... Элджер вон целую книжку написал по этим вопросам -всякие обертки над указателями...
|
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
SerpentVV, он об "умных" указателях писал, а ты про обычные спрашиваешь.
Можешь попробовать сделать так: обращаешься к полю какому нить, которое в конструкторе проинициализировано константой, перехватываешь исключение, если исключения не было проверяешь на равность этой константе. |
|||
|
||||
| SerpentVV |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 27.11.2006 Где: Астрахань Репутация: 1 Всего: 1 |
Тогда все нужно решать в конструкторе-деструкторе... Можно и булевское поле прописать... Созда = true, не создан = false
|
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Sartorius, не факт, что поможет. По каким-то причинам "мудрости" компилера может получится (со всякими выраниваниями и делитами позже, чем мы написали), что память будет нормально доступна + возможна даже с нужным значением. А если память недоступна, опять таки, нет гарантии, что это выльется в экзепшен, хотя в большинстве компилеров это и так.
|
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
Ну вот надо константу подлиннее делать |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Но (как я уже говорил) может такое получится, что прога просто вылетит - никакого экзепшена мы не получим. Сие компилерозависимо.
|
|||
|
||||
| Gitulyar |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 31.1.2007 Репутация: нет Всего: нет |
Понятно. В общем с константой идея неплохая, мне даже нравится. Поэтому: Sartorius БОЛЬШОЕ СПАСИБО
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Откуда возьмется исключение? Константа - член класса никогда не записывается в константную память, ибо сидит вместе с остальными членами класса. Всегда можно написать const_cast<TYPE&>(pMyClass->someField) = XXX, и тебе за это ничего не будет. Т.е. константные члены класса - чисто семантический прием, вроде private\public секций. Такой шанс (попасть в неизменяемую память) есть у статической константы, но до нее по указателю на объект никак не доберешься (т.е. ей по барабану, создан объект или нет). Способ один. Все указатели сразу инициализировать. Либо нулем, либо указателем на объект. Других способов нет. -------------------- ... |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Gitulyar, читай внимательней - это вовсе не спасение. Более того, скорее всего ты просто получишь вылет. Возможно экзепшен.
Earnest, экзепешен мы хотим взять отсюда:
НО - повторюсь, скорее всего мы просто тупо вылетим. Стандарт не обещает вам экзепшенов в таких случаях. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
А что, все непроинициализированные указатели смотрят в нижнюю область? Что-то не замечала. Если "повезет", то получишь Access violation, только ловить его нужно через обработку структурных исключений, хотя может и catch (...) поймает. Но если указатель имеет другое значение, то ничего не произойдет, если по нему не писать. И даже в этом случае, ошибку ты получишь вовсе не сразу, а в зависимости от того, что испортишь. В большом коде все может долгое время работать, пока где-нибудь совсем в другом месте не подвинешь чуть-чуть код...
-------------------- ... |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
Earnest, идея была такая : вот у нас есть указатель и мы не знаем историю операций, которая с ним произошла до этого. reinterpret_cast приводим его к указателю на объект нашего класса, а в конструкторе этого класса одно из полей проинициализировано константой (достаточно большой по длине) и значение ее нам известно. Вот мы читаем ее и сравниваем с этим значением. Если она - то наш объект
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Угу, я поняла, только сразу после удаления объекта его память вовсе не стирается (до тех пор, пока кто-нибудь ее не займет).
Так что можно удалить объект, потом по старому указателю прочитать свою константу и привет. -------------------- ... |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
Earnest, ну это уже в деструкторе все можно учесть.
|
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
А я думал, что мы просто не итили указатель. То есть он указывает не пойми куда, то ест ьвылет очень вероятен. А SEH тем более плафтормазависим (онли винда). |
|||
|
||||
| Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Влезаю в сей баян.
Можно показать на примере, когда программист (если он не мазохист) не может знать историю указателя? ИМХО мнение Kuvaldis самое граммотное и правильное:
|
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
||||
|
||||
| SergeCpp |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 955 Регистрация: 8.8.2005 Где: At Home Репутация: 15 Всего: 124 |
Для проверок такого рода используются соответствующие функции: IsBadReadPtr and IsBadWritePtr test whether a given address/size represents a valid block of readable or writable memory for the calling process. These functions know how Windows® allocates memory internally, so they're good at finding bad pointers. Также IsBadCodePtr и IsBadStringPtr Вот тема аналогичная (трёхмесячной давности ) |
|||
|
||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Тот же совет: инициализировать. И еще один: не использовать оин пойнтер по разным назначениям. А то часто пишут такой код:
Самый рассадник для ошибок, особенно при сопровождении. Все должно быть локально: переменная объявляется непосредственно перед использованием и тут же инициализируется. Для других целей заводим другую переменную, не треснет компилятор. Добавлено @ 19:32 Сам же там написал: иногда помогают, но не всегда. Опять же, с их помощью нельзя определить, является ли указатель началом объекта, а только то, что он указывает на память, записав в которую ты не получишь исключения. -------------------- ... |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |