Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
   &#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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.008 c
2-1207834516
bagos
2008-04-10 17:35
2008.05.11
выход из зацикливания


2-1207662818
switch
2008-04-08 17:53
2008.05.11
Как изменить цвет QRShape


2-1208242787
Zloy_Funtik
2008-04-15 10:59
2008.05.11
Сохр. данных нескольких мемо полей относительно одного параметра


15-1206683227
oldman
2008-03-28 08:47
2008.05.11
Переход на летнее время и обратно (в Windows)


15-1206529654
Галинка
2008-03-26 14:07
2008.05.11
Можно ли как то в моцилле предопределить размер шрифта?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский