Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.037 c
8-1074919026
Builder
2004-01-24 07:37
2004.04.25
Автоматическое изменение окна...


1-1081620253
Liona
2004-04-10 22:04
2004.04.25
Как главную форму положить под все окна приложения?


1-1081247825
k@k
2004-04-06 14:37
2004.04.25
SideBar


6-1077359189
ProNix
2004-02-21 13:26
2004.04.25
TwebBrowser и фреймы


3-1080721154
Alexander Bakulin
2004-03-31 12:19
2004.04.25
Переделать Paradox программу для многопользовательского режима





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский