Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 03.05.2021
Сообщений: 3

Обработка исключения

04.05.2021, 01:11. Показов 1610. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Возникла проблема при создании калькулятора. Вся соль с вычислением факториала. При вычислении факториала очень большого числа выдаёт исключения типа "StackOverflowException".
Но дело в том, что само вычисление заключено в блок "try", и по сути после исключения должно кидать в "catch". Ошибку выдаёт ещё до блока "try". Я примерно понимаю, что из-за через чур огромного значения оно всё и падает, но хотелось бы узнать, можно ли всё-таки как-то сделать, чтобы исключение обрабатывалось. Заранее спасибо. Код снизу.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        private double fact(double num)
        //Ошибку выдаёт в этом месте{
            try
            {
                double a = (num == 0) ? 1 : num * fact(num - 1);
                return a; 
            }
            catch ()
            {
                textBox_out.Text = "Ошибка";
                return 0;
            }
        }
Добавлено через 19 минут
Скобочки после "catch" забыл убрать, поэтому ошибка не в них.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.05.2021, 01:11
Ответы с готовыми решениями:

Обработка исключения отсутствия офиса
Как можно обработать исключение отсутствия Офиса на компьютере, в частности, экселя? try { ...

Обработка исключения в конструкторе со списком инициализации
Есть такой код: public SM(Iwmsm, mh) : base(mh) { } Класс отвечает за работу со сканером. При вызове этого...

Обработка исключения
Как пропускать исключения такого вида? Нужно именно пропускать исключение, а не останавливать. Пытался сделать так, не получилось. ...

7
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
04.05.2021, 06:27
Цитата Сообщение от YaroIL Посмотреть сообщение
но хотелось бы узнать, можно ли всё-таки как-то сделать, чтобы исключение обрабатывалось.
Никак. Читаем документацию

Начиная с платформа .NET Framework 2,0 нельзя перехватывать StackOverflowException объект с try / catch блоком, а соответствующий процесс по умолчанию завершается. Следовательно, следует написать код для обнаружения и предотвращения переполнения стека. Например, если приложение зависит от рекурсии, используйте счетчик или условие состояния для завершения рекурсивного цикла.
2
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
04.05.2021, 10:35
В .NET Core 2.0 и выше есть метод RuntimeHelpers.TryEnsureSufficientExecutionStack() (пространство System.Runtime.CompilerServices), с помощью которого можно проверить наличие памяти в стеке на вызов среднестатистической функции.
Можно вызывать этот метод перед рекурсией и если он возвращает false — бросать перехватываемое исключение.
2
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
04.05.2021, 12:48
Цитата Сообщение от kolorotur Посмотреть сообщение
проверить наличие памяти в стеке на вызов среднестатистической функции.
Немного поигрался с этим методом, кажись оно делает нехилый такой запас по стеку( если после него все равно еще раз вызвать -- не вылетает), причем ориентируясь на идущий после него код (т.е. если даже упоротся и создать структуру на 8кБ, то всек равно стопорит). Кроме как вызывая небезопасный код и явное нарушение логики проверки, этот метод может как-то "ошибится" с расчетами?
0
0 / 0 / 0
Регистрация: 03.05.2021
Сообщений: 3
04.05.2021, 13:10  [ТС]
Попробую воспользоваться данным методом. Спасибо за подсказку, ребята.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
04.05.2021, 19:05
Цитата Сообщение от Wolfdp Посмотреть сообщение
Кроме как вызывая небезопасный код и явное нарушение логики проверки, этот метод может как-то "ошибится" с расчетами?
Насколько я понимаю ее работу, она просто берет количество оставшейся в стеке памяти и сравнивает ее с количеством, которое использует под локальные и параметры некая "среднестатистическая" функция.
Как определяется эта среднестатистичность — одним авторам известно. Наверное просканировали гору репозиториев, подбили статистику, взяли значение с пика.
Учитывает ли она размер текущего фрейма — не знаю, в доках не сказано, а исходники не смотрел.
Но, судя по вашим тестам, этот метод может как недооценить, так и переоценить количество свободной памяти — в зависимости от того, насколько потребление памяти методом далеко от среднего.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
05.05.2021, 08:30
Мое изначальное предположение что "ориентируясь на идущий после него код" явно ошибочное. Попробовал через структуру определить сколько резервирует памяти стека, получилось что-то около 100КБ. Что-то мне подсказывает что для таких структур рекурсия впринципе противопоказана.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    class Program
    {
        static int i = 0;
        static void Main(string[] args)
        {
            var maxsize = Marshal.SizeOf(new Item());
            Console.WriteLine($"{maxsize / 1024}kB {maxsize % 1024}B");
            Console.ReadKey();
            Test();
            Console.WriteLine(i);
            Console.ReadKey();
        }
 
        static void Test()
        {
            i++;
            if (!RuntimeHelpers.TryEnsureSufficientExecutionStack())
                return;
            Test();
            Process();
        }
 
        static void Process()
        {
            var item = new Item();
        }
 
    }
 
    public struct Item
    {
        public Block10000B D0;
        public Block10000B D1;
        public Block10000B D2;
        public Block10000B D3;
        public Block10000B D4;
        public Block10000B D5;
        public Block10000B D6;
        public Block10000B D7;
        public Block10000B D8;
        public Block10000B D9;
 
        public Block1000B B0;
        public Block1000B B1;
        public Block1000B B2;
        public Block1000B B3;
        public Block1000B B4;
        public Block1000B B5;
 
        public Block96B F0;
        public Block96B F1;
        public Block96B F2;
        public Block96B F3;
        public Block96B F4;
 
        public int I0;
    }
 
    public struct Block10000B
    {
        public Block1000B B0;
        public Block1000B B1;
        public Block1000B B2;
        public Block1000B B3;
        public Block1000B B4;
        public Block1000B B5;
        public Block1000B B6;
        public Block1000B B7;
        public Block1000B B8;
        public Block1000B B9;
    }
 
    public struct Block1000B
    {
        public Block96B F0;
        public Block96B F1;
        public Block96B F2;
        public Block96B F3;
        public Block96B F4;
        public Block96B F5;
        public Block96B F6;
        public Block96B F7;
        public Block96B F8;
        public Block96B F9;
        public long L0;
        public long L1;
        public long L2;
        public long L3;
        public long L4;
    }
 
    public struct Block96B 
    {
        public long L0;
        public long L1;
        public long L2;
        public long L3;
        public long L4;
        public long L5;
        public long L6;
        public long L7;
        public long L8;
        public long L9;
        public int I0;
        public int I1;
        public int I2;
        public int I3;
    }
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.05.2021, 09:16
Цитата Сообщение от Wolfdp Посмотреть сообщение
Попробовал через структуру определить сколько резервирует памяти стека
Мощная структура
Можно проще:
C#
1
2
3
4
5
6
unsafe static void Process()
{
   const int KB = 1024;
 
   byte* data = stackalloc byte[150 * KB];
}
Или так, если не хочется добавлять флаг /unsafe:
C#
1
2
3
4
5
6
static void Process()
{
   const int KB = 1024;
 
   Span<byte> data = stackalloc byte[150 * KB];
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.05.2021, 09:16
Помогаю со студенческими работами здесь

Обработка исключения
Есть софт который запускается в несколько окон, иногда происходит какое то исключение и софт просто завершает свою работу, вроде обработал...

Обработка исключения
Привет , как сделать что бы при FormatException предлагало еще раз ввести число и так бесконечно пока не будет сделано все правильно , у...

Обработка исключения в WebMethod
Добрый день! Начал осваивать C# и сталкнулся с некоторой проблемой. Сделал Web-сервис, отлаживаю его в браузере, ввел не корректное...

Обработка исключения FileNotFoundException
Здравствуйте! Тут, собственно, такая проблема. Сижу делаю учебную задачку, нужно было из обычного изображения сделать полутоновое. Но я...

Обработка исключения DivideByZeroException
Нужно разработать 2 класса . В первом должно быть 2 переменные типа int, конструктор, который их инициализирует и метод, который ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru