Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.22;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.031 c
3-1091087814
Serge1
2004-07-29 11:56
2004.08.22
Добавление поля в ADOTable1.Fields


1-1091873765
Alexis
2004-08-07 14:16
2004.08.22
На форме не появляется TStatusBar


1-1091902043
Star
2004-08-07 22:07
2004.08.22
Разбор строки по флагу


1-1091639532
bloodman
2004-08-04 21:12
2004.08.22
Вызов функции главной программы из dll.


3-1091089438
Hermit
2004-07-29 12:23
2004.08.22
Вертикальный текст в QRLabel