Помогите с ООП - страница 3

 
Vasiliy Sokolov #:

Ок. Я не понимаю. А вы понимаете? Точно понимаете? Точно точно?

Спор сводится к следующему утверждению:

...

То было не об общем споре, а о ситуации, касающейся одного поста, и я объяснил в чем проблема. Ладно, катастрофы не случилось.

 

Объявил массив double x[268435448]; 

Такой же массив в функции OnStart().

Еще сделал рекурсивный вызов с глубиной LONG_MAX.

Никаких проблем. 

 
fxsaber #:

Не использовать статические массивы?

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

 
Andrei Trukhanovich #:

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

Хотелось бы иметь способ получить список статических переменных/массивов и их размеры. Наверное, нужен анализатор кода, как здесь сделано.

ЗЫ Наверное, статический string-массив и double-массив - совсем разные вещи.

MQL5 Program Packer
MQL5 Program Packer
  • www.mql5.com
This is MQL5 project packer: assemble all source and resource files from dependencies into a single ZIP.
 
fxsaber #:

ЗЫ Наверное, статический string-массив и double-массив - совсем разные вещи.

string по сути внутренний класс, состоящий из указателя и int размера, т.е. для double массив будет занимать условно в 1.5 раза меньше места

не думаю что на это есть смысл сильно заморачиваться, если только у вас нет статических массивов с миллионами элементов.

 
fxsaber #:

Не использовать статические массивы?

Выходит в MQL по сути есть четыре вида данных:

  • Статические, предопределенные данные. Вшиваются в программу во время компиляции и больше не изменяются. Располагаются в некой области памяти private. Например к ним относятся статические массивы вида char[1024].
  • Данные управляемые вручную через указатели. К ним относятся экземпляры классов, но определенные через указатель, например CFoo* bar, где bar экземпляр класса CFoo. Такие экземляры будут иметь тип POINTER_DYNAMIC. Данный тип хранения наиболее проблемный, хотя в большинстве случаев не требуется.
  • Данные, управляемые сборщиком мусора виртуальной машины mql, в которой исполняется программа. К ним относятся экземпляры классов. Указатель на объект относящийся к такому типу будет иметь вид POINTER_AUTOMATIC. А сами такие объекты располагаются или в куче этой виртуальной машины или в private секции. Как конкретно зависит от данных, их размера видимо и как там у разработчиков. Этой информации нет. К таким данным относятся пользовательские классы например. Любое определение экземпляра класса без указателя определяет этот тип хранения. Например CFoo bar определяет экземпляр bar класса CFoo, указатель на который освобождать не надо. Все операции по освобождению выполняет виртауальная машина. Не нужно использовать оператор delete, а следовательно и сталкиватся с проблемой leaked objects. 
  • Данные, расположенные на стеке. К ним относятся прежде всего локальные переменные функций. Т.е. когда мы пишем int a = 5 внутри какой-либо функции, то верхушка стека перемещается на 4 байта вверх, тем самым выделяя нужный объем памяти. Возможно в MQL к типам хранимым на стеке относятся и структуры (я никогда не проверял если честно). Такие данные занимают немного места, и даже с учетом цепочки вызовов вложенных функций, стек в целом требует гораздо меньше памяти чем куча. Данный тип хранения используется автоматически, о нем не надо думать.

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

Для иллюстрации сказанного, можете сравнить первончальный код предполженный Ihor Herasko и этот же код приведенный мной к форме POINTER_AUTOMATIC. Нет ни каких лишних проверок и инициализаций, нет вызова оператора delete 60 000 000 раз. Все это экономит силы, время и, что не маловажно, ресурсы, при том ощутимо. Если разобратся, то необходимости работы с указателями практически никогда нет. Всегда можно написать такой алгоритм, где бы эта работа сводилась бы либо к минимому, либо вообще к нулю. Например в моих кодах я никогда не управляю объектами вручную, просто в этом как-то не возникает необходимости. Что касается статических массивом то иногда и приходится использовать, например что бы вшить в программу нужные ей данные, но это на столько спецефические вещи, что обычным пользователям они я предполагаю не нужны. Лучше всего использовать готовые коллекции типа CArrayObj, либо свои собственные. Сейчас шаблоны и возможности MQL позволяют создать довольно гибкие вещи которые существенно лучше статических массивов.

 
Нет в эмкуле сборщика мусора.
 

Vasiliy Sokolov #:

Статические, предопределенные данные. Вшиваются в программу во время компиляции и больше не изменяются. Располагаются в некой области памяти private. Например к ним относятся статические массивы вида char[1024].

Если массив не инициализирован,

int A[] = {1, 2}; // Инициализация
int B[2];         // Без инициализации

зачем его зашивать в EX5?

 
fxsaber #:

Если массив не инициализирован,

зачем его зашивать в EX5?

Да, верно, неинициализированные не вшиваются конечно. Инициализированые вшиваются. Но размер обоих типов определяется во время компиляции и больше не меняется. Т.е. статические массивы условно можно разделить на две группы.

 
Dmitry Fedoseev #:
Нет в эмкуле сборщика мусора.

Официально как бы да. Неофициально, многие штуки свидетельствуют что он все-таки есть:

  • В MQL нет указателей. Вместо них используется нечто, что очень их напоминает. 
  • В MQL нет прямого выделения памяти как в Си например;
  • Программы на MQL исполняет некая виртуальная машина. Об этом Ренат писал вскольз и неидиножды;
  • Можно определить экземляр класса, который будет освобожден автоматически. Значит есть какой-то механизм, который следит за этими экземплярами и освобождает их при необходимости. Что это, если не сборщик мусора?
  • Любые экземпляры, инициализированые через указатель, и не освобожденные должным образом, будут помечены как leaked objects при выходе из программы. Будет напечатано их количество и общий размер потерянной памяти. Программа с утечками памяти даже не пройдет валидацию в Маркете. Следовательно все объекты, даже выделяемые вручную, учтены, известны и о них знает система. Это одна из классических задач, которые решает сборщик мусора.
Причина обращения: