![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Освобождение ресурса в finally
Arinyshka © (2008-04-23 12:17:00)
Страницы: < 1 2 ... 14 15 16 17 18 19 20 ... 32 33 >
Не подскажете еще один момент:
Есть процедура, выглядит примерно так
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]). Заменил весь контент, идущий, после перевода хэлпа, на более правдоподобную информацию (в основном копи-пастом из этой ветки :)
Прошу профи оценить правдоподобность изложенного в ней материала. Если по Вашему мнению все правильно, то оставлю как есть, иначе же все что необходимо - исправлю. Главное, чтобы она приносила, как минимум, больше пользы, чем вреда :)