Форум: "Потрепаться";
Текущий архив: 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