Форум: "Основная";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизНадежность программ на Delphi Найти похожие ветки
← →
vertal (2004-04-05 01:11) [0]Хочу обсудить надежность программ на Delphi
Меня смущает работа GetMem:
Предположим , есть такой код
...
Var
...
p:Pointer;
...
Begin
...
if (MaxAvail>=256)then GetMem(p,256);
...
End.
Я не уверен , что на "then" не произойдет передача управления
другому процессу в Windows , и этот другой процесс может отобрать себе
часть памяти , в результате чего отработка GetMem(p,256) будет
неуспешной.Получается , что пользоваться встроенным менеджером памяти вообще
нельзя? Или все GetMem() заключать в блоки try?
И еще операции со строками :что , получается , что каждый оператор , который
может приводить к увеличению длины динамической строки , нужно заключать в
блок try?
try
s1:=s1+#13#10;
except
...
end;
← →
Fay © (2004-04-05 02:52) [1]Про try - это правильно мыслишь. Тока вот всё, что ты тут нам так здорово расписал не имеет никакого отношения к Delphi лично.
Это относится ко всем проограммам.
← →
Broot (2004-04-05 03:05) [2]Вообще то у винды есть виртуальная память и всякие там файлы подкачки. Так что, чтобы исчерпать память, нужно очень постараться...
← →
Fay © (2004-04-05 03:11) [3]Ничего особенного для этого не требуется. Я однажды попытался открыть 15Mb-й xml Explorer-ом... Когда он сожрал 1.5 Gb и попросил ещё пришлось его пристрелить.
← →
KSergey © (2004-04-05 08:06) [4]> vertal (05.04.04 01:11)
У вас несколько превратные представления о надежных программах.
Задача надежной программы сосит в том, чтобы гарантированно освободить все занимаемые ресурсы, а вовсе не в том, чтобы не побеспокоить пользователя окошечком с красным значком.
Так, например, в связи с GetMem напрашивается следующий шаблонный код:GetMem(p, ..);
try
...// работаем с выделенной памятью
finally
FreeMem (p);
end;
Что тут важно: если нам не удасться получить память (в GetMem) - система сгенерит исключение, работы процедуры будет прервана, пользователь получить сообщение и нехватке памяти.
Если память таки выделится - то в случае каких либо проблем (исключений) внутри блока try/finally мы обязательно, гарантированно вызовем FreeMem и освободим память. Пользователь так же получит сообщение о возникшей проблеме.
Только не надо вносить GetMem в try/finally!! почему? подумайте сами, что произойдет в этом случае при ошибах на выделении памяти.
Про строки - я вообще не панял. Что беспокоит?? Дельфи гарантирует, что при любых проблемах память, распределяемая ею динамически (в частности, под строки), будет освобождена. О чем беспокоимся??
← →
Verg © (2004-04-05 08:48) [5]Где-то я видел такие дела
A := B;
if A <> B then { Тут запись в лог-файл об ошибке RAM}
А вообще, как тут не вспомнить про старую деву, свечку и то, что она на свечку надевала, дабы "Чего не вышло"...
← →
Fay © (2004-04-05 08:50) [6]>> A := B;
>> if A <> B then { Тут запись в лог-файл об ошибке RAM}
Это уже клиника... 8)
← →
Verg © (2004-04-05 08:55) [7]
> Это уже клиника... 8)
- это называется паранойя.
← →
Fay © (2004-04-05 08:57) [8]Во спасибо! А я всё думал, как это слово пишется. 8). А то, бывает, само просится, чтобы его написали, а - никак ... Ну и получается, что "голова тоже на обочине".
← →
Verg © (2004-04-05 10:00) [9]Нет, Fay, уж какие тут к черту шутки - дело сердёздное:
http://www.psychiatry.ru/lib/smul_paranoja/index.cgi?11
← →
vertal (2004-04-06 00:23) [10]2 Fay
> Про try - это правильно мыслишь. Тока вот всё, что ты тут нам
> так здорово расписал не имеет никакого отношения к Delphi лично.
>Это относится ко всем проограммам.
По-моему , это не относится ко всем программам .Так , в СИ , если не ошибаюсь , основной функцией для выделения памяти является malloc , а она при неудаче просто возвращает NULL вместо всяких исключений , и это можно проверить и прореагировать.Тут не возникает возможность изменения распределения памяти другим приложением между ее проверкой и фактическим выделением .
← →
Alex Konshin © (2004-04-06 00:41) [11]Начальный вопрос поставлен неверно: GetMem выделяет память в виртуальной памяти процесса, так что никакой другой процесс на это повлиять не сможет. Если же речь идет про потоки, то GetMem работает немного по-другому в случае многопоточного приложения, есть даже специальный флаг для многопоточного приложения и этот флаг устанавливается именно для менеджера памяти. Как он называется - на вскидку не помню, а искать сейчас лень, да и не об этом вопрос был.
← →
KSergey © (2004-04-06 08:50) [12]> [10] vertal (06.04.04 00:23)
> По-моему , это не относится ко всем программам .Так , в
> СИ , если не ошибаюсь , основной функцией для выделения
> памяти является malloc , а она при неудаче просто возвращает
> NULL вместо всяких исключений , и это можно проверить и
> прореагировать.Тут не возникает возможность изменения распределения
> памяти другим приложением между ее проверкой и фактическим
> выделением .
Я правда совершенно не понял выделенную фразу, но не понятно чем вас смущает: в Си после выделения - вы проверяли. А тут - не надо ничего проверять! Если что-то не пройдет - будет исключение, ф-ция прервется - вот и все. Проверять-то зачем?? Если не получилось - то что вы хотите сделать?
← →
Miwa © (2004-04-06 11:19) [13]Все же рискну спросить по вопроссу KSergey © (05.04.04 08:06)[4]:
А почему нельзя GetMem вносить внутрь блока try? Всю жизнь имення так и делал, кстати говоря.
← →
Fay © (2004-04-06 11:36) [14]В нек. смысле, нет блоков try. Есть блоки try..except и try..finally. Вы про какой спросили?
P.S
Сам знаю, что я не KSergey 8)
← →
Андрей Сенченко © (2004-04-06 11:36) [15]Miwa © (06.04.04 11:19) [13]
Потому что суперджинс.
Сравните 2 вариантаtry try
GetMem() GetMem()
finally except
FreeMem() FreeMem()
end end
← →
Матлабист (2004-04-06 11:49) [16]
var
A: Pointer;
begin
A := SysGetMem(1024*1024*1024);
if not Assigned(A) then ShowMessage("SysGetMem returns nil");
end;
Только Exception намного удобнее...
> А почему нельзя GetMem вносить внутрь блока try? Всю жизнь
> имення так и делал, кстати говоря.
Ошибка при выделении памяти приведет к тому, что FreeMem вызвется для блока, для которого память не была выделена. В Windows это не страшно --- Invalid pointer operation. А в DOS могла біть непритность вроде зацикливания ;)
← →
vertal (2004-04-07 01:33) [17]> Проверять-то зачем??
> Если не получилось - то что вы хотите сделать?
Положим , у меня есть два варианта решения задачи:первый требует больше памяти , но быстрее .Если он не проходит , то я могу попытаться применить второй вариант.Мне было бы удобней просто проверять указатель на Nil.Хотя , если ,как говорит Alex Konshin , "GetMem выделяет память в виртуальной памяти процесса, так что никакой другой процесс на это повлиять не сможет." , то и вариант с проверкой через MaxAvail меня устраивает.Хотя еще больше мне понравился вариант с SysGetMem.
← →
Alex Konshin © (2004-04-07 02:56) [18]Не, ну косвенно, конечно, повлиять может, если уж и своп весь забит, но при этом уже и сама система работает нестабильно.
А кто мешает самому выделять память? Я, например, в некоторых случаях, когда нужна память на время, просто беру память страницами с помощью VirtualAlloc, а когда нужно освободить отдаю их тоже всем скопом.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.034 c