Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Уничтожение объекта.


Страницы:   1 2

pathfinder ©   (2008-04-14 13:26:00) 

Здравствуйте!

Подскажите пожалуйста, почему при попытке уничтожить объект, который не был создан методом free возникает ошибка EAccessviolation?


procedure test;
var
 obj: tobject;
begin
 try
   exit;
 finally
   obj.Free;
 end;
end;


oxffff   (2008-04-14 17:36:00) [1]


> Anatoly Podgoretsky ©   (14.04.08 16:42) [21]


> Procedure SomeProc( constv: TObject),


Можно просто Procedure SomeProc(v: TObject)

только это не спасет.

Procedure SomeProc(v: TObject)
begin
v.free;
end;


Anatoly Podgoretsky   (2008-04-14 16:42:00) [2]

> oxffff  (14.04.2008 16:10:18)  [18]

Именно есть переменная, которая не контролируется и нет разницы локальная она или глобальная. Это осетрина второй свежести.


Anatoly Podgoretsky   (2008-04-14 16:41:00) [3]

> Kolan  (14.04.2008 16:09:17)  [17]

Вот вот, а всего то надо сделать контролируемое свойство и в принципе уничтожить проблему.
Но это уже все относится к robust application - у Борланда в руководстве посвящено целая глава этому.
Но не тяжело и без Борланда дойти до идеи написания безопасных приложений, правила и логика простые в принципе.


Anatoly Podgoretsky   (2008-04-14 16:39:00) [4]

> oxffff  (14.04.2008 16:03:16)  [16]

Я же не о хаках, а о нормальном написание, даже в этом случае надо было написать Procedure SomeProc(const v: TObject), но если нужен var, то надо принять меры, например сначала уничтожить, а только потом вызывать процедуру, или аналогичное, в зависимости от логики.


oxffff   (2008-04-14 16:10:00) [5]


> Kolan ©   (14.04.08 16:09) [17]


Это сабака одна и та же.


Kolan   (2008-04-14 16:09:00) [6]

>
> Ну это вы погорячились.

Так это собака «местная». Внешняя — это когда:

var
v: TObject

procedure
begin
 v := TObject.Create
 try
   …
 finally
   v.Free;
 end;
end;

proceure
begin
 v.Free;
end;


oxffff   (2008-04-14 16:03:00) [7]


> Anatoly Podgoretsky ©   (14.04.08 15:48) [15]


Мое маленькое уточнение относилось к Palladin ©.

Хотите поговорить об инициализации. Давайте поговорим.

Переменная локальная, неинициализированая, нет повторного использования,

В вашем случае переменная инициализированна вами перед первым условием.

>в следующий раз все начинается с нуля

С какого нуля?

Free всегда отработает правильно, утечки не будет, AV не будет. Ни одна внешняя собака ее не испортит.

Ну это вы погорячились.

Procedure SomeProc(var v: TObject)
....

procedure
var
v: TObject
begin
 v := TObject.Create
 try
   ...
 SomeProc(v);
 ...
 finally
   v.Free;
 end;
end;


Anatoly Podgoretsky   (2008-04-14 15:48:00) [8]


> А где я сказал что можно?

Так я тоже вроде не упоминал "можно", я говорил о том, что не играет роли первоначальная инициализация, интересует только правильное значение на протяжение всей жизни программы.
Вот подобный код будет всегда корректно работать

procedure
var
 v: TObject
begin
  v := TObject.Create
  try
    ...
  finally
    v.Free;
  end;
end;


Переменная локальная, неинициализированая, нет повторного использования, в следующий раз все начинается с нуля, не требуется знать ее состояние. Free всегда отработает правильно, утечки не будет, AV не будет. Ни одна внешняя собака ее не испортит.
А теперь сравни


> if Assigned(V) then


повторное использование и никакой гарантии, что V имеет допустимое значение.


Anatoly Podgoretsky   (2008-04-14 15:42:00) [9]

> Palladin  (14.04.2008 14:59:11)  [11]

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

v := Create
...
free
...
...
free

Вот переменная инициализирована, но второй Free вызовет ошибку. И рассматривай ситуацию не линейно как здесь, а более комплексно. Особенно для случая повторного использования.


Anatoly Podgoretsky   (2008-04-14 15:38:00) [10]

> korneley  (14.04.2008 14:54:10)  [10]

> Потом снова придет :))

И не просто придет, а с жалобой.


oxffff   (2008-04-14 15:07:00) [11]


> Anatoly Podgoretsky ©   (14.04.08 14:52) [9]


А где я сказал что можно?


Palladin   (2008-04-14 14:59:00) [12]


> Anatoly Podgoretsky ©   (14.04.08 14:52) [9]

Ну не говори так уж категорично то, если бы я точнознал что локальная переменная o:TSomeObject будет инициализироваться в Nil, я бы со спокойной совестью писал бы так же как и в [0]. При разработке класса, я прекрасно знаю что все поля будут инициализированны в 0(Nil), потому в деструкторе меня не волнует Nil агрегированный объект или нет. Это красивое решение: при возникновении исключения в конструкторе безопасно вызывать сразу деструктор. За шо борланду - респект :)


korneley   (2008-04-14 14:54:00) [13]


> Вот укажи мне то место, где я сказал, что я его создаю?
Не, ну, если так ставить вопрос... Только он ведь увидит, что ошибки нет (пока) и возрадуется. Потом снова придет :))


Anatoly Podgoretsky   (2008-04-14 14:52:00) [14]

> oxffff  (14.04.2008 14:25:05)  [5]

Ну и бог с ними, как инициализируются, так и разинициализируются.
Нельзя удалять несозданый объект, вне зависимости от состояния переменной.
И программиста не должно волновать его состояния, не стоит писать код с повторным использованием переменных.


Ega23   (2008-04-14 14:52:00) [15]


> Мнэ... Эта, что, новый способ создать объект такой? :)


Вот укажи мне то место, где я сказал, что я его создаю?


Palladin   (2008-04-14 14:51:00) [16]

ну да... AFAIK - строки, дин. массивы, варианты, олеварианты... все что имеет отношение к типам с управляемым временем жизни неявно инициализируется... правда я на этом вопросе сильно не заморачивался...


korneley   (2008-04-14 14:49:00) [17]


> Ega23 ©   (14.04.08 13:52) [4]
> procedure test;
> var
> obj: tobject;
> begin
> obj := nil;
> try
>   exit;
> finally
>   obj.Free;
> end;
> end;

Мнэ... Эта, что, новый способ создать объект такой? :) Автор ведь поверит.


oxffff   (2008-04-14 14:25:00) [18]


> Palladin ©   (14.04.08 13:30) [2]
> потому что локальные перменные распологаются в стеке и никак
> не инициализируются, соответственно заполненны мусором


Некоторые все же инициализируются.


Ega23   (2008-04-14 13:52:00) [19]

procedure test;
var
obj: tobject;
begin
obj := nil;
try
  exit;
finally
  obj.Free;
end;
end;


pathfinder   (2008-04-14 13:48:00) [20]


> Palladin ©   (14.04.08 13:30) [2]


Спасибо!


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо