быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
1 | |
Создать отдельный стек для функции29.11.2011, 22:26. Показов 3640. Ответов 44
Метки нет (Все метки)
необходимо. Мне надо вызывать рекурсивную функцию; при этом происходит переполнение стека, мне бы хотелось бы это контролировать.
g++ не поддерживает обработку SEH- исключений, отловить переполнение стека, как, впрочем и другие я не могу. Программа падает просто и всё. вызов рекурсивной функции в отдельном потоке с созданным и, как следствие, контролируемым стеком (билиотека pthread) рассамтриваю только в качестве ПОСЛЕДНЕГО варианта. Спасибо, кто откликнется Добавлено через 48 минут Только что в отладчике OllyDbg исполоьзовал такой приём: выделял объём памяти и вручную менял регистр ESP, чтобы он указывал на эту память и всё получалось, эта память работала как стек. Попробую такую идею замутить с аммесблерными вставками, они нужны будут для изменения ESP, если чё, отпишусь.
0
|
29.11.2011, 22:26 | |
Ответы с готовыми решениями:
44
Создать стек для символов. Максимальный размер стека вводится с экрана. Создать функции для ввода и вывода элементов стека. Ввести эталонный символ. Как создать отдельный поток для функции? Как создать стек для рекурсивной функции? Создать отдельный класс для пользователей |
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
30.11.2011, 17:32 [ТС] | 21 |
Он спотыкается на данных c_n_k(40, 19)
просто у меня недостаточно высокая квалификация, чтобы не спросить об этом.
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
30.11.2011, 18:04 | 22 |
это связано с неточностью представления чисел с плавающей точкой и погрешностями при делении. Сам алгоритм правилен. Если хочешь, создай тип данных "рациональная дробь" и используй его при делении (опционально, используй длинные числа, если хочешь работать с большими значениями), и будет тебе *абсолютная* точность. Ну или просто используй тот язык, в котором все это есть
попробуй расписать сам цикл на бумажке, я думаю, все прояснится Добавлено через 17 минут дабы не быть голословным, вот реализация именно этого алгоритма на хацкеле: Код
import Data.Ratio ((%)) c :: Integral a => a -> a -> Integer c n k = round $ product $ map (\i -> (n - k + i) % i) [1..k] Код
> c 40 19 131282408400
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
||||||
30.11.2011, 18:33 [ТС] | 23 | |||||
Именно это мне и не нравится и я знаю чё надо делать и я уже так делаю. Я использую класс VERYLONG
Но даже если бы у меня не было такого класса, я бы не стал писать такой код. Я понимаю, мои соображения никому не интересны, но всё же: да, базара нет, придираться к тому, что результат получается очень большим и как следствие, некорректным, это значит быть ниже пояса. Но надпись-то какую-никакую предупреждающую можно было вывести? Не знаю, чё автор хотел этим алгоритмом сказать. Мне кажется, это тот случай, когда этот простой, в общем-то алгорим нуждается в непростой и некрасивой обёртке. В частности, убрать КУДА ПОДАЛЬШЕ тип double и обеспечить абсолютную точность. ...Что, собсно, я и реализую. Ибо, я написал для себя подобную прогу но когда она спотыкалась на таких маленьких числах как 19 и 40, не смог этим удолетвориться, уж извините. +++++++++++++++++++++++++++++++++++++++++++++++++ Но это ерунда всё. Не ерунда заключается в том. чо я нигде не говрил о сумме сочетаний. Рекурсия у меня применяется не в нахождении суммы, а в выводе сочетаний, например из пяти по 3 без возвращения и без учёта порядка.
0
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|||||||||||
30.11.2011, 19:14 | 24 | ||||||||||
double возвращается правильный
во всяком случае на программу
http://joemath.com/math124/Cal... torial.htm http://www.calculatorpro.com/c... alculator/ просто для int'a мантисса переполняется а погрешности с double вообще практически нету
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
01.12.2011, 03:59 | 25 |
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
01.12.2011, 11:15 [ТС] | 26 |
Конечно, если бы я сказал об этом раньше это было бы хорошо. Но:
и код
НУ если человек понимает... Ну вот, тут-то и хорошо было бы его поправить, но я не мог не оставить без внимания код. Если бы я сделал и то, и другое, разговор распараллелился бы. Ну его. Надо быть последовательным. Сперва одно, потом другое.
0
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
||||||
01.12.2011, 11:37 | 27 | |||||
kravam, я вам сильно сочуствую, но все же вам нужен был отдельных стек для этого?
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
01.12.2011, 13:00 [ТС] | 28 |
Нет стек мне нужен был не для этого.
И знаете, я написал для чего нужен стек: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Такое впечатление, что своё гоняет просто. Второй раз за тему. Добавлено через 1 минуту Nameless One, у меня тут не полигон для демонстрации кодов.
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||||||
01.12.2011, 13:43 | 29 | |||||
да не нужен для этого "отдельный стек"! Вот держи:
Код
0 1 2 0 1 3 0 1 4 0 2 3 0 2 4 0 3 4 1 2 3 1 2 4 1 3 4 2 3 4 Count = 10
1
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
01.12.2011, 13:47 | 30 |
Nameless One, не рушь его иллюзии
стек нужен, с ассемблерными вставками
1
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
||||||
01.12.2011, 15:44 [ТС] | 32 | |||||
Так и мне не нужен! Вы читайте внимателльно, вы же не читаете тему. И код мне ваш без надобности, чай у меня свой есть и мой покомпактнее будет.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Так вот, докладываю, если я вывожу сочетавния из m по n, у меня глубина рекурсии n. Считаем: каждая функция принимает пять параметров, плюс адрес возврата плюс ещё какая-нибудь херь, максимум ячеек 10, каждая занимает 4 байта, итого 40 ячеек. На одну функцию. Переполнится стек. если я буду применять рекурсию? А прикинем Предположим, ввыводим сочетания из 30 по 15 (ибо 30/2== 15, наибольшее количество вариантов). Так вот, по моим подсчётам, это займёт три года. Примерно, конечно. Я выводил эти значения на экран и перикидывал в меньшую (то есть невыгодну для меня сторону) как часто меняется одно из полей... Проверяйте, в общем Если будем брать ещё большие значения,например из 32 по 16, то это уже 30 лет Так, а глубина рекурсии составит всего 16*40= 640 байт при том, что стандартный стек 22E000 байт. То есть стандарнтый стек windows, он не то, что не переполнится. Он в ПРИНЦИПЕ не переполнется. Плюс код такой аккуратный. Ну это ладно, каждый кулик своё болото хвалит ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Вопрос: а на фига тогда мне сдался этот отдельный стек? Ответ: компактный безопасный я не умею писать сразу, так вот в процессе тык скыть написания кода у меня частенько переполняется стек. Вот отдельный стек мне нужен для процесса тык скыть написания программ. Это основное. Понимаете, для отладки. А для готового кода мне отдельный стек без надобности. Я, конечно, мог это написать в первом сообщении но смысл? Тем более, челу и так всё понятно чё мне надо. Вы меня можете спросить, а чем тебя стандартный-то стек не устраивает, ведь вновь созданный точно также переполнится (хоть в процессе отладки, хоть как)? Отвечаю: переполниться-то он переполнгится, но я хочу сделать так, чтобы вывести предупреждающее сообщение. А так как у меня компилятор g++, он напрось не ловит системные исключения, то есть абсолютно. И переполнение вновь созданного стека я хотел отслеживать вручную ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
01.12.2011, 18:28 | 33 |
ну не ты ли говорил, что твою функцию нельзя заменить на рекурсивную? А мы просто опровергали твое утверждение. А лучшим аргументом, естественно, является работающий код
система какая? Если *nix, то valgrind вроде бы умеет ловить переполнение стека. В принципе, его (переполнение) можно и в отладчике увидеть, если внимательно посмотреть на бэктрейс. Также посмотри в сторону ключей -fstack-check и -fstack-protector, может что полезного нагуглишь. А твое решение с собственным стеком (ИМХО) выглядит слишком костыльно.
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
||||||
01.12.2011, 23:12 [ТС] | 34 | |||||
а ну тогда прошу прощения.
Добавлено через 3 часа 36 минут Nameless One, а вообще извольте прояснить ситуацию с этим кодом:
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
02.12.2011, 04:19 | 35 |
kravam, ограничение данного алгоритма в том, что исходный вектор должен представлять первые n натуральных чисел (с нулем), т.е. {0, 1, 2, ..., n - 1}. Но это ограничение легко обойти, если ввести дополнительный вектор. Причем изменить нужно будет только функцию dump
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
02.12.2011, 11:36 [ТС] | 36 |
я бы обязательно предупредил, а вдруг бы я взялся его использовать?!
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.12.2011, 11:51 | 37 |
При условии, что у тебя нет бесконечной рекурсии...
Добавлено через 2 минуты Как сделать чтоб не рухалась: Добавляешь счётчик глубины рекурсии. статическая переменная, которая увеличивается при входе и уменьшается при выходе из рекурсивной функции. Глубину рекурсии ты примерно знаешь, поэтому проверяешь значение счётчика и выкидываешь исключение при необходимости. 4 страницы галимотьи читать не стал, если это уже было написано - извиняюсь.
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
02.12.2011, 12:30 [ТС] | 38 |
Я этот способ рассматриваю и имею ввиду, но дело в том, что при отладке установить глубину рекурсии- это дорогого стоит. Это я щас по готовому продукту могу определить глубину рекурсии. А в процессе его изготовления- нет.
Хотя способ, несомненно хорош ДАЖЕ В ПРОЦЕССЕ НАПИСАНИЯ ПРОГРАММЫ, но привязываться итогда придётся к верхушке стека, к регистру ESP и размеру стека. Троудоёмко довольно. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Но даже и в этом случае вот какая есть сложность (но ты не принимай на своё счёт, это ведь и моя идея, просто неозвученная): Дело в том, по каждому вызову функции этот счётчик должен увеличиваться на величину (кадр стека?), равную тому, что занимают локальные даные рекурсивной функции. Допустим, примерно я это количество найду и накину пару тройку для надёжности байт. Но если алгоритм построен так, что рекурсивная функция вызывает не только себя, а какую-нибудь другую функцию, нерекурсивную? А если ещё и вызывает по некоторому условию? А если и в цикле? Так что к сожалению этот счётчик должен увеличиваться на чёрт его знает какое значение байт.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.12.2011, 12:38 | 39 |
На единицу. ++ на входе и -- перед выходом.
Точное максимальное значение не обязательно. Примерную сложность алгоритма всегда можно оценить. Если навскидку у тебя глубина 20 вызовов, поставь счётчик на 1000. Или на 100. Предполагать, сколько переменные займут в стеке - бесполезно. Есть выравнивание, есть "перетусовывание" компилятором. Кое что вообще в стек не попадает. В дебаге добавляется "неизвестное" количество дополнительных данных для контроля повреждений стека. Счётчик считает глубину. Всё. +1 и -1. Я даже на "бесконечных" циклах счётчик использую иногда.
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,686
|
|
02.12.2011, 12:55 [ТС] | 40 |
Ну ясно всё, неубедительно. Я уже говорил у меня очень низкая квалификация для некоторых вещей. В частности, я не возьмусь определять глубину стека до определённого момента ни примерно, никак. Такой момент наступает, как правило, когда прога готова.
Но при готовой проге вступают в силу другие соображения, а именно: я железно знаю, чо глубина рекурсии не превысит, например 100. То есть счётчик мне просто не нужен, я знаю, что он никогда не будет больше 100 и всё тут. Видишь, как получается: пока проги нет, хорошо бы использовать счётчик да глубину рекурсии не определить. А когда прога готова и можно определить глубину рекурсии- счётчик уже не нужен. Жизнь вообще сложная штука.
0
|
02.12.2011, 12:55 | |
02.12.2011, 12:55 | |
Помогаю со студенческими работами здесь
40
Создать отдельный управляемый поток для бесконечного процесса Как создать в Yii и применить для модуля отдельный config? создать стек для с++ Функции для записи данных в отдельный файл txt Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |