Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Вниз

Delphi + pointer = ?   Найти похожие ветки 

 
Kurtevich   (2004-08-03 12:38) [0]

Вымораживает то, как Дельфя обращается с указателями: когда вызываешь хваленый TObject.Free, он обьект-то освобождает, но переменная все еще на что-то указывает, и проверка obj<>nil возвращает true, со всеми вытекающими отсюда Access Violations... Поэтому приходится всякий раз писать obj.Free; obj := nil;, а это напряжно... Больше всего бесит, что когда вызываешь Obj.Free, который нахваливают за то, что он проверяет obj на nil, он все равно дает AccessViolation если obj=nil, поэтому приходится писать if obj<>nil then obj.Free;

Вобщем, мой вопрос короткий: WHY!?!?! И что вы обо всем этом думаете?


 
TUser ©   (2004-08-03 12:40) [1]

FreeAndNil
или
.Free;
:=nil;


 
Kurtevich   (2004-08-03 12:41) [2]

Удалено модератором
Примечание: Не ругаться


 
Sergey_Masloff   (2004-08-03 12:42) [3]

>поэтому приходится писать if obj<>nil then obj.Free;
слабо глянуть в текст Free()?

Есть метод FreeAndNil() если так уж лень писать myVar := nil;


 
KSergey ©   (2004-08-03 12:44) [4]

> [2] Kurtevich   (03.08.04 12:41)
> > FreeAndNil
> п...ц! а это не то, что я уже написал в вопросе?

Нет, про ф-цию FreeAndNil ты не упоминал.

> Больше всего бесит, что когда вызываешь Obj.Free, который
> нахваливают за то, что он проверяет obj на nil, он все равно
> дает AccessViolation если obj=nil

Вранье наглое.


 
Sergey_Masloff   (2004-08-03 12:45) [5]

Кстати объяснение весьма прозаичное - откуда объект может знать что там на него указывает? Он знает какую память занимает он и высвобождает ее по команде. То есть делает что в его силах.


 
TUser ©   (2004-08-03 12:45) [6]

Удалено модератором


 
KSergey ©   (2004-08-03 12:46) [7]

> Kurtevich   (03.08.04 12:38)
> но переменная все еще на что-то указывает

Разумеется! А разве ее кто-то чистил?? Или как всегда на всемогущего Пушкина надежда?


 
ламер ©   (2004-08-03 12:46) [8]

я думаю, что надо просто хорошо продумывать алгоритм. и не будет тогда таких глупых проблем.

создание объекта - работа с ним - уничтожение. и всё. если ПРАВИЛЬНО пользоваться механизмом обработки исключительных ситуаций, то никаких проверок на nil даже не надо производить.


 
Kurtevich   (2004-08-03 12:47) [9]


> слабо глянуть в текст Free()?

а смысл туда смотреть? и так понятно, что там написано
if self<>nil then free();
только вот если self=nil то до проверки внутри этой процедуры дело не доходит... Error! Access violation at address 0x000! Would you like to send report to microsoft corp.?!


 
TUser ©   (2004-08-03 12:48) [10]

А гляньте в втеку про логи. Если объекты создаются, уничтожаются, потом опять создаются и так много раз - то надо проверять.


 
Kurtevich   (2004-08-03 12:48) [11]


> если ПРАВИЛЬНО пользоваться механизмом обработки исключительных
> ситуаций, то никаких проверок на nil даже не надо производить.

интересно... а можно конкретизировать?


 
KSergey ©   (2004-08-03 12:49) [12]

> [9] Kurtevich   (03.08.04 12:47)
> а смысл туда смотреть? и так понятно, что там написано
> if self<>nil then free();

А вот посмотрел бы - и увидел, что все не так :) Впрочем, можно не смотреть - и так понятно, что не так.
А ошибка у тебя в другом совсем месте, уверяю.


 
Игорь Шевченко ©   (2004-08-03 12:52) [13]


> Вымораживает то


Греться надо.


> когда вызываешь хваленый TObject.Free, он обьект-то освобождает,
> но переменная все еще на что-то указывает, и проверка obj<>nil
> возвращает true, со всеми вытекающими отсюда Access Violations...
>


Так и задумано


> Больше всего бесит, что когда вызываешь Obj.Free, который
> нахваливают за то, что он проверяет obj на nil, он все равно
> дает AccessViolation если obj=nil


Руки выпрями. Помогает.


 
Kurtevich   (2004-08-03 12:52) [14]


> А вот посмотрел бы - и увидел, что все не так

вот странно - посмотрел, а все оказалось именно так! правда вместо free destroy - я конечно это и имел ввиду, просто привычка на автопилоте всегда писать Free... суть от этого не меняется
> А ошибка у тебя в другом совсем месте, уверяю.

да нет у меня вобще никакой ошибке ни в каком месте... просто я не понимаю на хрена рекомендовать этот free как совершенно безопасный, если он ни хрена не работает?!


 
ламер ©   (2004-08-03 12:58) [15]

> Kurtevich   (03.08.04 12:48) [11]
> интересно... а можно конкретизировать?

например:


try
 MyObj := TMyObj.Create;
 try
   // если дошли до этого места, то объект создан.
   MyObj.DoSomeWork;
   // ...
 finally
   // были какие-либо исключения при работе или нет - объект
   // будет уничтожен.
   MyObj.Free;
 end;
except
 // ошибка создания объекта. память освобождается автоматически
 // и ничего уничтожать не надо.
end;


а теперь моё большое имхо. если в процессе работы, приходится проверять, создан объект или нет, значит сам алгоритм написан неверно.


 
KSergey ©   (2004-08-03 13:03) [16]

> [14] Kurtevich   (03.08.04 12:52)
> правда
> вместо free destroy ... суть от этого
> не меняется

Ага, конечно, не меняется
Толи работаем дальше, толи циклимся по полной :)

> я не понимаю на хрена рекомендовать этот free как совершенно
> безопасный, если он ни хрена не работает?!

Это кто, интересно, такое сказал? Покажите пальцем, плиз.
А вообще - есть правила работы с инструметном (дельфи). Работайте в рамках этих правил - и все будет здорово. Инструмент, увы, для другого просто не предназначен. С этим придется мириться.

> [15] ламер ©   (03.08.04 12:58)

А внешний try/except зачем? Для комментария? Или просто привычка все сообщения об ошибках давить? :)


 
ламер ©   (2004-08-03 13:06) [17]

> KSergey ©   (03.08.04 13:03)
> А внешний try/except зачем? Для комментария? Или просто
> привычка все сообщения об ошибках давить? :)
для комментария, т.к. это общий пример.


 
KSergey ©   (2004-08-03 13:08) [18]

Мне почему-то кажется, что в общем примере это как раз лишнее...

А вообще мне наиболее нравится такой общий пример (хотя и не всегда реализуемо по причине совпадения имен методов/свойств)

with TMyObj.Create do
try
...
finally
 Free;
end;


 
Digitman ©   (2004-08-03 13:09) [19]


> не понимаю на хрена рекомендовать этот free как совершенно
> безопасный, если он ни хрена не работает?!


все прекрасно работает

и рекомендация эта относится к методу объекта, который знать ничего не знает и знать не может и не должен о том, сколько переменных, ссылающихся на него, ты сподобился наплодить в своей программе ! Этот метод НЕ ОБЯЗАН вычищать за тобой то, что ты САМ обязан делать, если это требуется по твоей логике


 
TUser ©   (2004-08-03 13:12) [20]

Внешний - для обработок ошибок в конструкторе.


 
ламер ©   (2004-08-03 13:12) [21]

> KSergey ©   (03.08.04 13:08) [18]
просто бывают такие случаи, что работа должна продолжиться, невзирая на то, было ли исключение при создании объекта. да и вывести сообщение понятным для пользователя языком тоже не помешает.


 
Kurtevich   (2004-08-03 13:19) [22]


> try
>  MyObj := TMyObj.Create;
>  try
>    // если дошли до этого места, то объект создан.
>    MyObj.DoSomeWork;


неужели?.. непонятны всего несколько моментов:

а) какое исключение может сгенерироваться в конструкторе обьекта? то есть я не спорю, теоретически-то может (смотря у кого какие конструкторы), хотя в таком случае я и без всяких двойных try пойму что что-то не так :)
б) а если (и это более естественный случай) создание обьекта и его использование расположены по разным процедурам, а не в одном try... except statement?
в) на кой ... мне вобще какя-то проверка в данном случае?

вобщем, утверждение
> если в процессе работы, приходится проверять, создан объект
> или нет, значит сам алгоритм написан неверно
не доказано


 
Kurtevich   (2004-08-03 13:23) [23]


> Ага, конечно, не меняется
> Толи работаем дальше, толи циклимся по полной :)


как я уже сказал, насчет free я просто обшибся, смысл был в том, что надо обьект уничтожается если Self<>nil, поэтому суть не меняется.

при чем здесь сколько переменных я наплодил? зачем проверять self, если раз уж мы добрались внутрь процедуры, то self есть? ... его не может не быть :)


 
Anatoly Podgoretsky ©   (2004-08-03 13:23) [24]

Проверка переменной на нил говорит о попытке повторного использования этой переменной, в правильно написаной программе этого быть не должно, говорит о недостатках дизайна, подлежит переписыванию.


 
Sergey_Masloff   (2004-08-03 13:24) [25]

Kurtevich   (03.08.04 13:19) [22]
>а) какое исключение может сгенерироваться в конструкторе >обьекта? то есть я не спорю, теоретически-то может (смотря у >кого какие конструкторы), хотя в таком случае я и без всяких >двойных try пойму что что-то не так :)
Невозможность выделения какого-либо ресурса по причине отсутствия самого ресурса или прав на его использование

>б) а если (и это более естественный случай) создание обьекта и >его использование расположены по разным процедурам, а не в >одном try... except statement?
Что. Создал и отдал значение указателя. Тот кто взял отвечает за его высвобождение. Твоя задача - если то что собираешься отдавать не создал по тем или иным причинам - корректно верни nil

в) на кой ... мне вобще какя-то проверка в данном случае?


 
Digitman ©   (2004-08-03 13:28) [26]


> раз уж мы добрались внутрь процедуры, то self есть? ...
> его не может не быть


может !! считывается значение "битой" ссылки из переменной и прямой ссылкой передается как неявный параметр Self


 
ламер ©   (2004-08-03 13:31) [27]

> Kurtevich   (03.08.04 13:19) [22]
а) любое. EInOutError, EOutOfMemory, EOutOfResources и т.д. и т.п.
б) значит либо: 1) у вас жутко нетривиальный случай, 2) неверный алгоритм.
в) для нормального продолжения работы.

> вобщем, утверждение не доказано

ой, да я и не собираюсь никому ничего доказывать. это просто моё имхо. за всё время моей работы с дельфи такие случаи (с созданием/уничтожением в разных местах) возникали всего пару раз в результате выбора неверной стратегии. и при удачной перепланировке я всегда получал более интуитивно понятный и надёжный алгоритм.


 
Kurtevich   (2004-08-03 13:32) [28]

jesus... недостатки дизайна, подлежит переписыванию... что за гониво?
а если у меня есть процедура, в которую как параметр передается указатель на обьект, разве это плохой стиль программирования - прежде всего проверить, что бы он был valid?! откуда я знаю что происходило вовне этой процедуры - может система упала и забрала всю память с собой, а осталась висеть только моя прога на обугленных останках монитора... всякое бывает!
и что, повторное использование переменных - это плохо?! я не сомневаюсь что проффессиональные программисты обьявляют новую переменную каждый раз, когда им че-то надо... но это ж заманаться можно! :)


 
Digitman ©   (2004-08-03 13:35) [29]


> система упала и забрала всю память с собой


бред сивой кобылы


> не сомневаюсь что проффессиональные программисты обьявляют
> новую переменную каждый раз, когда им че-то надо


тоже чушь


 
ламер ©   (2004-08-03 13:35) [30]

> Kurtevich   (03.08.04 13:32) [28]
да, параметр в процедуре - это вариант, в котором действительно иногда бывает необходима проверка. чаще всего можно просто избежать вызова процедуры с указателем на несозданный объект.


 
Anatoly Podgoretsky ©   (2004-08-03 13:36) [31]

Ну если тебе тяжело, то переквалифицируйся в дворники, но и они сейчас работают со сложной техникой.


 
ламер ©   (2004-08-03 13:38) [32]

>если раз уж мы добрались внутрь процедуры, то self есть? его не может не быть :)

Self используется только для вызова виртуальных методов. т.к. Free - невиртуальный, то для его можно вызвать даже так:


TObject(nil).Free;


причём никаких исключений данный вызов не породит :)


 
Kurtevich   (2004-08-03 13:43) [33]


> бред сивой кобылы

согласен. так и замышлялось :)

> TObject(nil).Free;

а вот это я попробую!

> Self используется только для вызова виртуальных методов

то есть, если я правильно понял, я могу вызывать методы несозданного обьекта?! типа
TMYObject(nil).ConnectToMicrosoftComAndDeleteAllData???
весело... или эттот прикол распространяется только на TObject? вобще дельфя конечно умеет повеселить своими скрытыми возможностями :)


 
Kurtevich   (2004-08-03 13:44) [34]

i wonder, на фиг вобще создавать обькты, когда дельфя открывает такие горизонты в ООП!?!


 
Anatoly Podgoretsky ©   (2004-08-03 13:45) [35]

Есди это классовый метод (класса) то можешь, а если это метод объекта то нет, поскольку нет объекта.


 
Sergey Kaminski ©   (2004-08-03 13:49) [36]

Kurtevich   (03.08.04 13:32) [28]
> а если у меня есть процедура, в которую как параметр передается
> указатель на обьект, разве это плохой стиль программирования -
> прежде всего проверить, что бы он был valid?! откуда я знаю что
>происходило вовне этой процедуры


Да, в общем случае, это неважный стиль программирования. И вот почему.
Передача неверного параметра в процедуру ДОЛЖНА вызывать исключение внутри этой процедуры. При этом желательно, чтобы там даже не было подавления Exception. Тогда внешняя процедура легко может отследить (по возникшему эксепшену), что что-то пошло не так.


 
Kurtevich   (2004-08-03 13:51) [37]

я понял, люди, в чем источник нашего взаимонедопонимания!!!
вы слишком обращаете внимание на мелочи вроде того, что я написал free вместо destroy, спровоцировав тем самым рекурсивно бесконечную дисфункцию %(, или на то, что система якобы может забрать у меня всю память (ah jesus it"s a monstrous system from outer space!!!), хотя все это не важно в контексте смысла проблемы.
а теперь более конкретный вопрос: если я напишу
destructor TMyObject.Destroy();
begin
 inherited;
 Self := nil;
end;

чё будет?!... только не надо, пожалуйста писать "запусти, увидишь сам", или "хочешь фокус: я запускаю этот код на твоей машине и смотрю как плавится клавиатура..."... вопрос на самом деле серьезный :)


 
ламер ©   (2004-08-03 13:52) [38]

>Anatoly Podgoretsky ©   (03.08.04 13:45) [35]
> Есди это классовый метод (класса) то можешь, а если это метод
> объекта то нет, поскольку нет объекта.

не совсем так. я, например, для создания форм в ран-тайм использую:


type
 TfrmOption = class (TForm)
 ...
 public
   procedure Call;
 end;

...

procedure TfrmOption.Call;
begin
 Application.CreateForm(TfrmOption, frmOption);
 try
   frmOption.ShowModal;
 finally
   frmOption.Release;
 end;
end;


 
Kurtevich   (2004-08-03 13:54) [39]


> Есди это классовый метод (класса) то можешь, а если это
> метод объекта то нет, поскольку нет объекта.

%-( ооо, раздуплите меня пожалуйста.... я ни черта не понял в вышесказанном!
если я правильно понимаю ООП, то обект - это инициализированная переменная типа класс...
если предположить, что здесь имеется в виду, что метод класса - это когда обьект не создан, то в данном случае никаккого "если" быть не должно!


 
Sergey_Masloff   (2004-08-03 13:56) [40]

Kurtevich   (03.08.04 13:51) [37]
Ты считаешь ЭТО

destructor TMyObject.Destroy();
begin
inherited;
Self := nil;
end;

мелочи?!

Что ты вообще этим кодом хотел сделать?



Страницы: 1 2 3 4 5 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.036 c
4-1089724021
AHTOH
2004-07-13 17:07
2004.08.22
Изменение свойств шрифта у кнопки


14-1091638104
sasha_n
2004-08-04 20:48
2004.08.22
Структура файла SecEvent.Evt


14-1091775375
zamkom
2004-08-06 10:56
2004.08.22
Excel


4-1089281283
han_malign
2004-07-08 14:08
2004.08.22
Имя текущего пользователя, из под сервиса...


14-1091715614
MacroDenS
2004-08-05 18:20
2004.08.22
Кто нибудь может объяснить????





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский