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

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

Освобождение ресурса в finally


Страницы:   1 2 ... 14 15 16 17 18 19 20 ... 32 33

Arinyshka ©   (2008-04-23 12:17:00) 

Не подскажете еще один момент:
Есть процедура, выглядит примерно так

procedure TSetPayFrm.BtnAddImageClick(Sender: TObject);
var  TempBitmap:TBitmap;
begin
if not(opendialog1.Execute) then  exit;
try
 TempBitmap  := TBitmap.Create;
 TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
end;

На освобождение  TempBitmap.Free; выдает варнинг
[Warning] uSetPaymentMain.pas(313): Variable 'TempBitmap' might not have been initialized
Не смертельно, но непонятно... почему варнинг? При изменениии условия и включении всей конструкции в один блок begin..end ситуация не менялась.


Экс-Оригинал   (2008-04-28 14:02:00) [321]


> Восхищенный   (27.04.08 14:42) [310]
> > Loginov Dmitry ©   (27.04.08 14:31) [309]
>  Главное вот что - ты понимаешь, что совершаешь почти преступление?
>


Бред какой...


Экс-Оригинал   (2008-04-28 13:59:00) [322]


> . Если отстаивать последовательно
> объектную модель, то нужно было б создать временный объект,
>

Не всегда нужно плодить сущности ради выполнения кода в единственном месте.


Leonid Troyanovsky   (2008-04-28 11:22:00) [323]


> Экс-Оригинал   (27.04.08 15:39) [312]

Во-ще, nested routines выглядят весьма неуклюже внутри методов,
если там пользуют объекты, а не простые типы данных.
Отсюда и корявые решения. Если отстаивать последовательно
объектную модель, то нужно было б создать временный объект,
включающий все эти стримы, парсеры и т.д., и, скорее всего,
ReadCustomVariant должен быть методом, а не вложенной функцией.

--
Regards, LVT.


Восхищенный   (2008-04-28 10:53:00) [324]

"Что изменилось? (прим.: с появлением Интернета).

Правильно. Сеть терпима к объему. Необязательно писать рассказы, необязательно учиться, как в три страницы вместить Человека, Мир и Сюжет. Можно сразу начинать с большой фантастической эпопеи.

Кстати, параллельно с рассказами я тоже писал свои "Кровавые бани". Первые три были полной ерундой. На четвертой произошел какой-то перелом, переход количества в какое ни есть, но качество. И четвертая повесть уже была издана на бумаге.

Но существуй в те годы интернет - могли бы выйти и первые три.

И очень вероятно, что четвертая и пятая повести оставались бы на том же самом уровне".

© Сергей ЛУКЬЯНЕНКО.


Восхищенный   (2008-04-28 10:44:00) [325]

http://neogranka.com/forum/showthread.php?t=1461


Игорь Шевченко   (2008-04-28 10:01:00) [326]

Loginov Dmitry ©   (28.04.08 09:17) [325]


> Судя по ассемблерному коду, до вызова конструктора никакого
> try..except не вставляется


RTFM: System.pas, _ClassCreate

А.П. верно поправил


> Да, эмпирическая. В качестве рекомендации. Считаете, что
> лучше ее совсем не указывать?


Считаю.

Считаю, что луше прислушаться к рекомендациям и не писать вовсе


Loginov Dmitry   (2008-04-28 09:19:00) [327]

> а 4 - это эмпирическая константа или как ?

Да, эмпирическая. В качестве рекомендации. Считаете, что лучше ее совсем не указывать?


Loginov Dmitry   (2008-04-28 09:17:00) [328]

Судя по ассемблерному коду, до вызова конструктора никакого try..except не вставляется. Поэтому, как ни крути, получается что-то наподобие этого:

> try
>  { Ваш код конструктора }
> except
>   Destroy;
>   raise;
> end;

Проще, наверно, указать, что это всего-лишь псевдокод, а как на самом деле - смотрите asm...


Anatoly Podgoretsky   (2008-04-28 08:41:00) [329]

> Loginov Dmitry  (28.04.2008 08:04:23)  [323]

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


Loginov Dmitry   (2008-04-28 08:04:00) [330]

> "В секции finally должна выполняться обработка любых возникающих
> в ней исключений, в противном случае будет невозможно выполнить
> обработку других исключений. "
>
> - что-то я крайне редко видел код, подобный следующему:
>
> try
> ....
> finally
> try
>   ...
> except
>   ...
> end;
> end;


Не бейте! Это просто перевод хэлпа :)


> точнее, так:
> try
>  { Ваш код конструктора }
> except
>   Destroy;
>   raise;
> end;


Спасибо! raise Пропустил :(


> "Если при выделении памяти функцией AllocMem() произойдет
> исключение, FreeMem() освободит память только для ненулевых
> указателей"
>
> что, FreeMem проверяет на nil ?


Этот код просто взят из VCL. Как я могу его осуждать? Это прихоть разработчиков. Формально FreeMem проверяет на nil, но это - недокументированная фича.


> это тоже смущение для неокрепших душ, а вдруг поверят? Тебе
> же тогда второй приз надо будет выдавать, первый Архангельскому,
> а вот правильный код
>
> constructor TSomeClass.Create;
> begin
>  { Ваш код конструктора }
> end;


В смысле сам вызов конструктора защищен try..except? Ладно, подправим!

> Кстати у тебя есть большое желание писать, но надо подождать
> (если желание не пройдет), пока уровень мастерства возрастет,
> а пока только вред наносишь.


Дык я и не пишу. Всего лишь исправляю давнишнюю статью, чтобы к ней не было нареканий.


Германн   (2008-04-28 01:41:00) [331]

Ну да. Вот Коля Карих (и почему меня постоянно тянет написать Рарих :) тоже наверно стремился сеять разумное доброе и вечное. А сколько жертв его стремления?


Игорь Шевченко   (2008-04-28 00:54:00) [332]

Экс-Оригинал   (28.04.08 00:47) [319]

Если честно - жалко. Потому что ерунды в сети и в магазинах и без автора хватает. Человек не просто, написал и успокоился, ему надо, чтобы читали, чтобы типа разумное доброе и вечное сеять.


Экс-Оригинал   (2008-04-28 00:49:00) [333]


> Loginov Dmitry ©   (27.04.08 23:41) [313]


Если ечть желание писать, то обязательно договариваться с рецензентами - пусть читают, потом апрвить, опять на рецензию отдавать...
И только после этого - выкладывать в общество...


Экс-Оригинал   (2008-04-28 00:47:00) [334]


> Говорил же - не пиши.


Жалко, что-ли? -(


Игорь Шевченко   (2008-04-28 00:29:00) [335]

Anatoly Podgoretsky ©   (28.04.08 00:21) [315]


> это тоже смущение для неокрепших душ, а вдруг поверят? Тебе
> же тогда второй приз надо будет выдавать, первый Архангельскому


Ага, сознаюсь, повелся.
Это код _ClassCreate выглядит так, с try..except


Anatoly Podgoretsky   (2008-04-28 00:26:00) [336]

> Anatoly Podgoretsky  (28.04.2008 00:24:16)  [316]

Кстати у тебя есть большое желание писать, но надо подождать (если желание не пройдет), пока уровень мастерства возрастет, а пока только вред наносишь.


Anatoly Podgoretsky   (2008-04-28 00:24:00) [337]

> Anatoly Podgoretsky  (28.04.2008 00:21:15)  [315]

Ах да, для конструктора Destroy не надо делать, Destroy только для созданых в конструкторе или далее в коде объектов, и конечно без какого либо (кроме редких случаеу) Assingned, для необъектов или если рашрушение в коде, но и тогда не стоит, лучше сделать obj := nil


Anatoly Podgoretsky   (2008-04-28 00:21:00) [338]

> Игорь Шевченко  (28.04.2008 00:05:14)  [314]

"Код конструктора выглядит примерно так:

constructor TSomeClass.Create;
begin
try
 { Ваш код конструктора }
except
  Destroy;
end;
end;

"

точнее, так:
try
 { Ваш код конструктора }
except
  Destroy;
  raise;
end;

-----------

это тоже смущение для неокрепших душ, а вдруг поверят? Тебе же тогда второй приз надо будет выдавать, первый Архангельскому, а вот правильный код

constructor TSomeClass.Create;
begin
  { Ваш код конструктора }
end;

destructor Destroy
begin
  Destroy;
end;


Игорь Шевченко   (2008-04-28 00:05:00) [339]

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

- что-то я крайне редко видел код, подобный следующему:

try
 ....
finally
 try
   ...
 except
   ...
 end;
end;

"Не следует использовать уровень вложенности операторов try..finally больше 4-х, т.к. это снижает читабельность кода"

а 4 - это эмпирическая константа или как ?

"Код конструктора выглядит примерно так:

constructor TSomeClass.Create;
begin
 try
  { Ваш код конструктора }
 except
   Destroy;
 end;
end;

"

точнее, так:
 try
  { Ваш код конструктора }
 except
   Destroy;
   raise;
 end;


"Правильно разработанный код деструктора теоретически не должен ни при каких обстоятельствах провоцировать возникновение исключения."

почему не должен - оно просто передастся наверх и вся радость.

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

не любого.

"Если при выделении памяти функцией AllocMem() произойдет исключение, FreeMem() освободит память только для ненулевых указателей"

что, FreeMem проверяет на nil ?

"In Delphi code, FreeMem destroys the variable referenced by P and returns its memory to the heap. If P does not point to memory in the heap, a runtime error occurs.If P points to a structure that includes long strings, variants, dynamic arrays, or interfaces, call Finalize before calling Freemem .

P is a variable of any pointer type previously assigned by the GetMem procedure.

Size specifies the size in bytes of the dynamic variable to dispose of; if specified, it must be exactly the number of bytes previously allocated to that variable by GetMem .
After calling FreeMem, the value of P is undefined.
Note: It is preferable to use the New and Dispose procedures rather than GetMem and FreeMem. When using New and Dispose , there is no need to explicitly call Finalize ."


Говорил же - не пиши.


Loginov Dmitry   (2008-04-27 23:41:00) [340]

> И, желая помочь начинающему в понимании try..finally, ты
> пишешь вот такой страшный пример (кстати, четко показывающий,
> что ты и сам толком не понимаешь того, о чем пишешь). А
> этот бедняга начинающий, не в состоянии даже понять, что
> пример страшный, и думает, что так и надо делать.
>
> Выглядишь ты при этом довольно смешно, но не это главное.
> Главное вот что - ты понимаешь, что совершаешь почти преступление?


Признаю все свои ошибки. И по поводу статьи, и по поводу примеров и т.д. и т.п.
Если разобраться, то в VCL (начиная с Delphi7) действительно нет ни одного участка, в котором исключение в конструкторе привело бы к утечке памяти. Видимо, не просто так они там все подправили. Наверно, от них требуют (или требовали) придерживаться существующего стандарта, наказывая за произвол :) Либо же на самом деле вероятность ошибки в конструкторе - ненулевая. Ну так или, VCL как и всегда является примером для подражания :)

Статью переписал (ссылка в [33]). Заменил весь контент, идущий, после перевода хэлпа, на более правдоподобную информацию (в основном копи-пастом из этой ветки :)
Прошу профи оценить правдоподобность изложенного в ней материала. Если по Вашему мнению все правильно, то оставлю как есть, иначе же все что необходимо - исправлю. Главное, чтобы она приносила, как минимум, больше пользы, чем вреда :)


Страницы:   1 2 ... 14 15 16 17 18 19 20 ... 32 33

Наверх

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