Какие события вызывают переполнение стека?

 

Не первый раз получаю при компилировании советника ошибку: internal stack overflow-simplify the program, please.

Хотелось бы знать, значениями каких параметров заполняется стек, которые могут вызвать его переполнение. На форуме модераторы указывают на некоторые возможные причины ошибки ('Опять проблемы с компилятором.') ('Помогите разобраться с ошибкой в Метатрейдере'), в частности, на недопустимо большую вложенность операторов цикла и разветвления, большое количество массивов и пр., и как с этим бороться. Например, перевести часть кода в подпрограммы.

В некоторых случаях это неудобно и неэффективно: при обращении к подпрограмме из цикла или при использовании массивов, которые как правило заполняются полезной информацией именно в циклах. При этом глобальными массивами, которые бы не надо было передавать в подпрограммы в качестве значений параметров, язык MQL4 не располагает.

Кроме того мои изыскания показали странную катину. Удаление из советника, содержащего около 2000 строк, нескольких "безобидных" никак логически не связанных операторов типа ObjectCreate, ObjectSet, RefreshRates и подобных (имею ввиду НЕ операторы присваивания, разветвлений или циклов) приводит к исчезновению ошибки! Похоже, есть ограничение на общее количество использованных операторов в программе? Заранее благодарен всем за просвещение.

 
dokpiknik >>:

Не первый раз получаю при компилировании советника ошибку: internal stack overflow-simplify the program, please.

Хотелось бы знать, значениями каких параметров заполняется стек, которые могут вызвать его переполнение. На форуме модераторы указывают на некоторые возможные причины ошибки ('Опять проблемы с компилятором.') ('Помогите разобраться с ошибкой в Метатрейдере'), в частности, на недопустимо большую вложенность операторов цикла и разветвления, большое количество массивов и пр., и как с этим бороться. Например, перевести часть кода в подпрограммы.

В некоторых случаях это неудобно и неэффективно: при обращении к подпрограмме из цикла или при использовании массивов, которые как правило заполняются полезной информацией именно в циклах. При этом глобальными массивами, которые бы не надо было передавать в подпрограммы в качестве значений параметров, язык MQL4 не располагает.

Кроме того мои изыскания показали странную катину. Удаление из советника, содержащего около 2000 строк, нескольких "безобидных" никак логически не связанных операторов типа ObjectCreate, ObjectSet, RefreshRates и подобных (имею ввиду НЕ операторы присваивания, разветвлений или циклов) приводит к исчезновению ошибки! Похоже, есть ограничение на общее количество использованных операторов в программе? Заранее благодарен всем за просвещение.

бывaет при некорректной рекурсии

при очень большой вложенности вызовов

--

попробуйте для начала увеличить стек


как вариант попробуйте последовательно комманды увеличения стека



#property stacksize 1024

или

#property stacksize 4048

или

#property stacksize 8096


#property stacksize 16192


---

если не поможет ищите ошибки в коде

--

в некоторых ситуациях просто достаточно увеличить стек

 
YuraZ писал(а) >>

бывет при некорректной рекурсии

при очень большой вложенности вызовов

--

попробуйте для начала увеличить стек

как вариант попробуйте последовательно комманды увеличения стека

#property stacksize 1024

или

#property stacksize 4048

или

#property stacksize 8096

#property stacksize 16192

---

если не поможет ищите ошибки в коде

--

в некоторых ситуациях просто достаточно увеличить стек

Прежде всего спасибо за ответ. #property stacksize не помогло.

Однако. У меня используется, похоже, "бесполезный" оператор ObjectSet(obj_order, OBJPROP_WIDTH, 1);. "Бесполезный", поскольку, если я не ошибаюсь, линия толщиной 1 рисуется по умолчанию. Верно? (Прошу ответить)

Я его использовал "для порядка". Так вот, я удаляю 11 таких операторов в произвольных местах программы и ошибка пропадает. При удалении 10-ти ошибка ещё есть. Похоже, что код правильный. И рекурсия ни при чём. Или я что-то упустил? Если нет, в чём причина такого "странного" поведения компилятора?

Ещё вот что. При последовательном удалении операторов ObjectSet(obj_order, OBJPROP_WIDTH, 1); место обнаружения ошибки компилятором сдвигается на один оператор вниз по программе до тех пор, пока не выходит за пределы программы. Тогда-то и исчезает ошибка. Создаётся ощущение, что с определённого момента компилятор не позволяет увеличивать объём (длину) программы, а не её сложность. В моём советнике около 1950 строк (несколько из них- до 20- комментарии). Как это понять и преодолеть? Заранее благодарю за ответ.

 
dokpiknik >>:

Создаётся ощущение, что с определённого момента компилятор не позволяет увеличивать объём (длину) программы, а не её сложность. В моём советнике около 1950 строк (несколько из них- до 20- комментарии).

Выделенное сомнительно, dokpiknik. Мне известно, что есть работающие проекты с гораздо большей длиной кода. Наверно, лучше спросить у Integer'a и komposter'a о том, какие самые большие по объему программы они создавали.

Ну а "бесполезные" операторы и правда лучше удалять, если то, что они делают, все равно устанавливается по умолчанию.

P.S. Кажется, еще Zhunko как-то обмолвился о своем проекте, который гораздо больше упомянутых 2000 строк.

 
dokpiknik >>:

Прежде всего спасибо за ответ. #property stacksize не помогло.

Однако. У меня используется, похоже, "бесполезный" оператор ObjectSet(obj_order, OBJPROP_WIDTH, 1);. "Бесполезный", поскольку, если я не ошибаюсь, линия толщиной 1 рисуется по умолчанию. Верно? (Прошу ответить)

Я его использовал "для порядка". Так вот, я удаляю 11 таких операторов в произвольных местах программы и ошибка пропадает. При удалении 10-ти ошибка ещё есть. Похоже, что код правильный. И рекурсия ни при чём. Или я что-то упустил? Если нет, в чём причина такого "странного" поведения компилятора?

Ещё вот что. При последовательном удалении операторов ObjectSet(obj_order, OBJPROP_WIDTH, 1)(obj_order, OBJPROP_WIDTH, 1); место обнаружения ошибки компилятором сдвигается на один оператор вниз по программе до тех пор, пока не выходит за пределы программы. Тогда-то и исчезает ошибка. Создаётся ощущение, что с определённого момента компилятор не позволяет увеличивать объём (длину) программы, а не её сложность. В моём советнике около 1950 строк (несколько из них- до 20- комментарии). Как это понять и преодолеть? Заранее благодарю за ответ.

1950 строк это точно не причина

есть программы на MQL4 более 10 тыс строк

и тут вряд ли виновата ее длина

есть сомнения что это из за длины

--

прописывать код работа которого не обязательна

т е умолчания эти коды не должны влиять на проблему стека

--

в коде как я понял нет вложенных циклов и нет рекурсии

возможно проблема во вложенном цикле

---

Один из Вариантов отослать код разработчикам!

если это ошибка компилятора то они ее исправят

---

но Вам как то надо аргументировать что это большая вероятность ошибки компилятора

---

в ином случае Вам надо искать ошибку самостоятельно

---

стараюсь как правило писать достаточно простые конструкции

у компилятора при компиляции моих кодов крыша не съезжала ни разу

ни разу не упирался в проблемы или ограничения компилятора

к примеру знаю что размер общего кол массивов у MQL4 ограничен ну и не пишу коды с огромным кол массивов

---

 
Mathemat >>:

Выделенное сомнительно, dokpiknik. Мне известно, что есть работающие проекты с гораздо большей длиной кода. Наверно, лучше спросить у Integer'a и komposter'a о том, какие самые большие по объему программы они создавали.

Ну а "бесполезные" операторы и правда лучше удалять, если то, что они делают, все равно устанавливается по умолчанию.

P.S. Кажется, еще Zhunko как-то обмолвился о своем проекте, который гораздо больше упомянутых 2000 строк.

Леш длина точно не влияет у Вадима кода на более чем 10тыс строк все работает

--

у меня были проекты на 3 - 5 тыс строк

 
YuraZ писал(а) >>

1950 строк это точно не причина

есть программы на MQL4 более 10 тыс строк

и тут вряд ли виновата ее длина

есть сомнения что это из за длины

--

прописывать код работа которого не обязательна

т е умолчания эти коды не должны влиять на проблему стека

--

в коде как я понял нет вложенных циклов и нет рекурсии

возможно проблема во вложенном цикле

---

Один из Вариантов отослать код разработчикам!

если это ошибка компилятора то они ее исправят

---

но Вам как то надо аргументировать что это большая вероятность ошибки компилятора

---

в ином случае Вам надо искать ошибку самостоятельно

---

стараюсь как правило писать достаточно простые конструкции

у компилятора при компиляции моих кодов крыша не съезжала ни разу

ни разу не упирался в проблемы или ограничения компилятора

к примеру знаю что размер общего кол массивов у MQL4 ограничен ну и не пишу коды с огромным кол массивов

---

Спасибо, YuraZ и Mathemat ! Вопрос в том, почему ПРИ НЕИЗМЕННОЙ ЛОГИКЕ ПРОГРАММЫ (все вложения, разветвления и пр. неизменны) ошибка исчезает, стоит только удалить несколько операторов, никак не влияющих на структуру?

Если исходить из того, что ошибки содержатся в программном коде, а компилятор работает правильно, ошибка со стеком должна оставаться.

Я удалял 11 упомянутых выше операторов из разных мест программы - в разнобой, рядом расположенные и пр. Результат один и тот же: при удалении до 10 операторов ошибка есть, при удалении 11 исчезает. "Мистика".

Кстати, массивов у меня всего 9, из них двумерных 3, одномерных - 6. Переменных около 100.

 

Скорее всего огромная часть кода помещена в одну функцию. Упрощайте функции, разбивая их на несколько.

Компилятор сразу об этом сообщает: "simplify the program, please."


ps: кстати, достаточно было прикрепить свой код прямо к вопросу и сразу же бы получили четкий ответ. иначе тут организовывается выставка ясновидящих.

 
Renat писал(а)
 
YuraZ писал(а) >>

1950 строк это точно не причина

есть программы на MQL4 более 10 тыс строк

и тут вряд ли виновата ее длина

Длина точно не виновата - эксперт на 19500 строк нормально работает. Как-то раз наталкивался на сообщение компилятора о невозможности сборки, но путём изменения кода (кажется, что-то вынес в Lib, либо разбил код на функции) всё решилось.

 
Renat писал(а) >>

Скорее всего огромная часть кода помещена в одну функцию. Упрощайте функции, разбивая их на несколько.

Компилятор сразу об этом сообщает: "simplify the program, please."

ps: кстати, достаточно было прикрепить свой код прямо к вопросу и сразу же бы получили четкий ответ. иначе тут организовывается выставка ясновидящих.

Приветствую Вас, Renat! Около 1500 из всего 1850 операторов моего советника находятся в "бесконечном" цикле в модуле int start(). Наибольшее количество вложений if, for и им подобных в "бесконечном" цикле 10. Слишком много?

Разбивать этот фрагмент программы на функции крайне нежелательно (если только альтернативного решения не найдётся, тут уж ничего не поделаешь), потому что в нём обрабатываются массивы в цикле. Любой из двух возможных вариантов решения проблемы - обращение при каждой итерации из цикла к подпограмме или программирование цикла в подпрограмме с передачей в неё массивов и возвращением результатов обработки массивов в вызывающую программу - приводят с существенному утяжелению программы и уменьшению скорости обработки.

И всё потому, что в MQL4 не предусмотрены глобальные массивы. Хотя, извините за банальность, один из основных применяемых процессов в программировании, если не основной, это обработка массивов в циклах. Получается, что с одной стороны нельзя писать программные блоки произвольной длины (создание подобных монстров само по себе радости не вызывает из-за неудобочитаемости), с другой стороны нет удобного средства разбивки программного кода на фрагменты (подпрограммы). Надеюсь, что это обстоятельство когда-нибудь разрешится. Сейчас остаётся исходить из того, что дано.

Кстати, преклоняю колено перед разработчиками языка, которые на мой взгляд сделали без того очень много в плане создания и совершенствования языка MQL4. Благодарю их и понимаю трудности.

Что касается пересылки кода, то реально несколько причин, почему я его не послал: не думал, что проблема сложная и не хотел обременять (кто будет добровольно анализировать чужой бред?). Хотел получить знания, а не готовое решение, к чему привык за всю жизнь. И, может быть, самое существенное. Многие из программистов (я в том числе) хотят создать уникального советника, вкладывают в него душу и "несбыточные" надежды и не торопятся опубликовать его. Извините меня за откровенность и доставленные неудобства. В любом случае "напрягать" быть ясновидящим я никого не хотел. Спасибо.

Причина обращения: