![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Уничтожение объекта.
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]
Спасибо!