Форум: "Начинающим";
Текущий архив: 2008.05.11;
Скачать: [xml.tar.bz2];
ВнизУничтожение объекта. Найти похожие ветки
← →
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
…
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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c