Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> FreeAndNil 
:(
    Опции темы
Delphist
  Дата 9.2.2007, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: нет
Всего: 3



Код

var
procedure MyFreeAndNil(var Obj);
begin
 Obj.Free;
 Obj := Nil
end;

Почему FreeAndNil(obj) и MyFreeAndNil(obj) имеют разный результат выполнения. Объясните пожалуйста.

Это сообщение отредактировал(а) Delphist - 9.2.2007, 13:04


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Rennigth
Дата 9.2.2007, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



В каком смысле?


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Delphist
Дата 9.2.2007, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: нет
Всего: 3



Цитата(Rennigth @  9.2.2007,  14:11 Найти цитируемый пост)
В каком смысле? 

Почему я спрашиваю данный вопрос. В своей проге я использую DBGridEh. В одной из колонок при клике по ячейке появляется раскрывающийся список(LookUp поля). Так вот если я начну закрывать форму с этим гридом при раскрытом списке, то выскакивает ошибка. После трудоемкой трассировки выяснил место ошибки:
Пример из DBGridEh:
Код

destructor TCustomDBGridEh.Destroy;
begin
 FIntMemTable := nil;
 if FStyle <> nil then
   FStyle.RemoveChangeNotification(Self);
 FColCellParamsEh.Free;
 Selection.Clear;
 FColumns.Free; FColumns := nil;
 ...


Делаю так, ошибка исчезает
Код

destructor TCustomDBGridEh.Destroy;
begin
 FIntMemTable := nil;
 if FStyle <> nil then
   FStyle.RemoveChangeNotification(Self);
 FColCellParamsEh.Free;
 Selection.Clear;
 FreeAndNil(FColumns)
 ...
Почему так происходит?



--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Rennigth
Дата 9.2.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



Цитата(Delphist @  9.2.2007,  13:32 Найти цитируемый пост)
Почему так происходит?

Точно не изза разницы как дестроить FColumns. Лезь в FColimns и смотри в чем проблема, и почему вылетает AV(думаю что AV).


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Delphist
Дата 9.2.2007, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: нет
Всего: 3



Цитата(Rennigth @  9.2.2007,  14:50 Найти цитируемый пост)
Точно не изза разницы как дестроить FColumns. 

Незнаю, незнаю... только вот AV пропадает.


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Rennigth
Дата 9.2.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



Код

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;


Разницы не вижу...  smile 

В таких случаях помогает чашка кофе(или чего покрепче), шапка шамана и бубен. smile 


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
MetalFan
Дата 9.2.2007, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Delphist, если пропалает AV в одном месте, это еще не значит, что оно не вылезет в другом ;)



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Delphist
Дата 9.2.2007, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: нет
Всего: 3



Цитата(MetalFan @  9.2.2007,  15:12 Найти цитируемый пост)
Delphist, если пропалает AV в одном месте, это еще не значит, что оно не вылезет в другом ;)

А что ей вылазить то, я структуру кода не менял. FreeAndNil и (Free + :=nil) выполняют по сути одно и тоже только 1-ый более безопасный.


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
MetalFan
Дата 9.2.2007, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(Delphist @  9.2.2007,  14:18 Найти цитируемый пост)
только 1-ый более безопасный

с чего это вдруг?!
оба способы НЕБЕЗОПАСНЫ если их применять неправильно... 
и вообще, программирование это небезопасная штука) так и лезут ошибки всякие! главное - уметь их правильно найти, локализовать и поправить.

з.ы. это я к тому, что замена Free+:=nil на FreeAndNil - это не выход. есть деятели, что пишут так:
Код

try try
//глючный код или вызов глючных функций
except finally end;

как вас такое? ошибки то не вылазят! значит тоже верное решение? а зачем их искать, если можно просто "спрятать" уведомления об их возниконовении?!


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Delphist
Дата 9.2.2007, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: нет
Всего: 3



Цитата(MetalFan @  9.2.2007,  15:54 Найти цитируемый пост)
как вас такое? ошибки то не вылазят! значит тоже верное решение? а зачем их искать, если можно просто "спрятать" уведомления об их возниконовении?! 

Вылезут. Потому как try execpt end; спасает от ошибок не связанных с памятью. А вот когда вы попытаетесь обраться к методу уже разрушенного объекта, при чем объект будет разрушен но не равен Nil а имеет адрес $0808088. Как вам это?

Это сообщение отредактировал(а) Delphist - 9.2.2007, 15:51


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
MetalFan
Дата 9.2.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



невылезут, если AV происходит в пределах try..except.
SEH "спасает"(читай ловит) от любых ошибок. а try except/finally end - это делфевая "обертка" над виндовым SEH.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
aktuba
Дата 9.2.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 2
Всего: 38



Может все дело в следующем:

Код

procedure MyFreeAndNil(var Obj);
begin
 Obj.Free;
 Obj := Nil
end


Ты делаешь объекты Free и объекты = nil, после ты пытаешься присвоить "ничему" nil.

Вот реализация FreeAndNil:

Код

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;


Попробуй так же...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
MetalFan
Дата 10.2.2007, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(aktuba @  9.2.2007,  17:54 Найти цитируемый пост)
Ты делаешь объекты Free и объекты = nil, после ты пытаешься присвоить "ничему" nil.

что-то не понял в смысл фразы.
ничего не мешает сделать
  lSomeObj.Free;
  lSomeObj := nil;

и ни к каким ошибкам это в идеале приводить не должно)
з.ы. если конечно же объект раньше не убит. или при умирании ничего за собой не тащит.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 10.2.2007, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 16
Всего: 459



На счет 
Код

procedure MyFreeAndNil(var Obj);
begin
 Obj.Free;
 Obj := Nil
end

Могу сказать одно, Obj, не является уже указателем на на объект, а указателем на указатель на объект.
Если передавать
Код

procedure MyFreeAndNil(Obj : TObject);
begin
 Obj.Free;
 Obj := Nil
end

то указатель на объект передается по значению, при этом объект Obj уничтожиться но исходный указатель не обнулиться, ведь передана не сама переменная указателя, а ее значение.
  Присвоение Obj := Nil; компилятор понимает не как зануление переменной объекта, которая на самом деле является указателем на объект, а зануление указателя на переменную, которая указывает на объект.
Проблемы возникают из-за того что делфи неявно разыменовывает указатели, причем может делать это цепочечно для доступа к полям и методам, так как-будто и нет вообще указателей. 
  Но при работе с такими переменными как с указателями (присвоение адреса это операция над указателем), неявное разименовывание запрещено, так это помешало бы проводить операции с указателями именно как с указателями, а не с их содержимым. Потому явное приведение
Код

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

является единственно верным.  Pointer(Obj) заставляет компилятор понять, то что нам нужна именно переменная объекта, а не указатель на нее и нужна она нам не для доступа к объекту, а для доступа к адресу записанному в ней (мы ведь приводим ее к указателю), запрещая компилятору различные интерепретации данной операции.
  Вообще операции приведения типа в делфи не являются таки простыми как это может показаться на первый взгляд. Приведение типов всегда является умными и может вызывать даже различные функции без нашего ведома. Так и в этом случае. Интерпретация в лоб Pointer(Obj) дала бы тот же результат, что и первый вариант, но в данном случае приведение является скорее сообщением компилятору о том что мы имеем ввиду записывая такую команду, ведь компилятор думает о том, что мы не знаем о создании неявного указателя на переменную объекта при передаче ее в качестве var параметра.
  Жуть да  smile . Мы должны думать о том, что компилятор думает о нас и действовать исходя из того как этого будет ожидать от нас компилятор.

Это сообщение отредактировал(а) Alexeis - 10.2.2007, 00:44


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 10.2.2007, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Alexeis, хорошо объяснил) аж я после 3х банок пива понял  smile 


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0832 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.