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

Вниз

Уничтожение объекта.   Найти похожие ветки 

 
pathfinder ©   (2008-04-14 13:26) [0]

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

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


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


 
Anatoly Podgoretsky ©   (2008-04-14 13:29) [1]

Потому что не создан.


 
Palladin ©   (2008-04-14 13:30) [2]

потому что локальные перменные распологаются в стеке и никак не инициализируются, соответственно заполненны мусором


 
pathfinder ©   (2008-04-14 13:48) [3]


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


Спасибо!


 
Ega23 ©   (2008-04-14 13:52) [4]

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


 
oxffff ©   (2008-04-14 14:25) [5]


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


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


 
korneley ©   (2008-04-14 14:49) [6]


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

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


 
Palladin ©   (2008-04-14 14:51) [7]

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


 
Ega23 ©   (2008-04-14 14:52) [8]


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


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


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

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

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


 
korneley ©   (2008-04-14 14:54) [10]


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


 
Palladin ©   (2008-04-14 14:59) [11]


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

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


 
oxffff ©   (2008-04-14 15:07) [12]


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


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


 
Anatoly Podgoretsky ©   (2008-04-14 15:38) [13]

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

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

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


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

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

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

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

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


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


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

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

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


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


> if Assigned(V) then


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


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


> 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;


 
Kolan ©   (2008-04-14 16:09) [17]

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

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

var
v: TObject

procedure
begin
 v := TObject.Create
 try
   &#133
 finally
   v.Free;
 end;
end;

proceure
begin
 v.Free;
end;


 
oxffff ©   (2008-04-14 16:10) [18]


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


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


 
Anatoly Podgoretsky ©   (2008-04-14 16:39) [19]

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

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


 
Anatoly Podgoretsky ©   (2008-04-14 16:41) [20]

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

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


 
Anatoly Podgoretsky ©   (2008-04-14 16:42) [21]

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

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


 
oxffff ©   (2008-04-14 17:36) [22]


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


> Procedure SomeProc(const v: TObject),


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

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

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



Страницы: 1 вся ветка

Текущий архив: 2008.05.11;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.023 c
15-1206533074
Тыщ
2008-03-26 15:04
2008.05.11
Ассемблер в Turbo Pascal 7.0


2-1207815713
azamatufa
2008-04-10 12:21
2008.05.11
TADOQuery - параметры...


15-1206933934
TPL
2008-03-31 07:25
2008.05.11
Если нету Com-порта


15-1206990222
Дмитрий С
2008-03-31 23:03
2008.05.11
Посоветуйте книги.


2-1208170710
djaUser
2008-04-14 14:58
2008.05.11
Загрузка файлов с инет.