Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Если вдруг захотите поспорить в Ренатом, то велкам.
эээ как бы вот это:
И еще один момент. Массивы объектов лучше создавать через указатель. Иначе получится массив в стековой памяти, которой очень мало:
Если чуток изменить пример, сделав объявление на локальном уровне и поставив не такое уж и страшное число, то компилятор уже прямым текстом пишет о том, в чем именно дело:
Если вдруг захотите поспорить в Ренатом, то велкам.В вашем же примере:
определяется вне функции, как глобальная переменная. Так какой здесь стек? Это куча.
В вашем же примере:
определяется вне функции, как глобальная переменная. Так какой здесь стек? Это куча.
Потрясающе! Василий, вы полезли в спор, не понимая о чем спорите, и не прилагая усилий, чтобы понять о чем спор?
Игорь и утверждает, что надо в куче, и эта строка кода из второго ("правильного") примера, который компилируется, в отличие от первого, который не компилируется (и в нем нет указателя).
Если чуток изменить пример, сделав объявление на локальном уровне и поставив не такое уж и страшное число, то компилятор уже прямым текстом пишет о том, в чем именно дело:
Если вдруг захотите поспорить в Ренатом, то велкам.На счет "не страшного". Как сказать. Стек по умолчанию 1МБ, а вы выделяете на нем ARRAY_SIZE*sizeof(Test), что явно больше
Это не проблема и тем более не потенциальная. Просто особенности работы с памятью в МТ. Вот статический массив:
А вот динамический массив:
В этом случае все компилируется и работает.
Идем дальше.
В первом случае память выделяется на этапе компиляции. То есть сегмент .data программы должен включать эти ARRAY_SIZE*sizeof(Test). Сколько там ARRAY_SIZE был?))) Если не ошибаюсь, то под 2ТБ .ex5 файл выходит))))
Во втором случае, как раз идет выделение в куче ARRAY_SIZE*sizeof(Test*) байт, т.е. 480ГБ,
double x[268435448]; в общем разделе компилируется.
268435449 - уже не компилируется
А в OnStart() скрипта 268435449 компилируется, причем в общем разделе оставил этот громадный массив x.
268435448*8=2 147 483 584 - это два гига.
***
А вот предел в функции: double x[268435456];
Смотрите в справе про стек:
Указывает размер стека для MQL5 программы, стек достаточного объема требуется в случае выполнения рекурсивных вызовов функций.
При запуске скрипта или эксперта на графике выделяется стек не менее 8Мб, для индикаторов свойство не работает - стек всегда фиксированного объема в 1Мб.
При запуске в тестере программе всегда выделяется стек в размере 16 Мб.
Надо полагать, стек используется только для рекурсивного вызова функций. Поэтому неважно какого размера будут статические массивы, для рекурсивного вызова стек останется таким, какой он есть.
Потрясающе! Василий, вы полезли в спор, не понимая о чем спорите, и не прилагая усилий, чтобы понять о чем спор?
Игорь и утверждает, что надо в куче, и эта строка кода из второго ("правильного") примера, который компилируется, в отличие от первого, который не компилируется (и в нем нет указателя).
Ок. Я не понимаю. А вы понимаете? Точно понимаете? Точно точно?
Спор сводится к следующему утверждению:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Помогите с ООП
Ihor Herasko, 2021.09.19 21:00
И еще один момент. Массивы объектов лучше создавать через указатель. Иначе получится массив в стековой памяти, которой очень мало:
Это неверное утверждение. Массивы в стеке не выделяются. Ни через указатели ни статически. Это легко проверить.
Второй момент: в примере используются указатели, но они там не нужны. Вот эквивалентный пример без болерплейта:
Выделяются те же 60 000 000 объектов с вызовом конструктора по умолчанию. При этом не надо вручную инициализировать, а потом освобождать память, что значительно (в разы) экономит время а код делает гораздо более безопасным простым и локаничным.
Проверяем. Делаем брейк и открываем в менеждере процессов. Вот в ProcessHacker:
В области private выделино 4 и 2 Гб соотвественно.
Проверяем размер стеков:
Стек скрипта 8 Мб и это максимальный стек.
Легко включить логику в голове и посчитать, что 60 000 000 объектов размером по 20 байт каждый займут более 1 Гбайта памяти. Ни какого стека не хватит что бы вместить это в себя.
При этом оба примера (и с указателями и без) дают то же профилирование. В стеке ничего не выделяется. Однако пример с указателями выделяет на 1 Гб больше памяти, в этом тоже легко убедится.
з.ы. Нельзя просто так взять и изменить максимальный размер стека во время выполнения программы. Максимальный размер стека является предопределенным и задается заранее, например при компиляции.
з.ы.ы. Чисто теоретически возможно небольшие статические массивчики выделять на стеке ( в mql это будет не явно). Но это может привести к большим проблемам, так как пользователь очень лекго может создать несколько таких массивов даже в разных сопряженных функциях и тем самым переполнить стек. Поэтому от такого самострела пользователей нужно обезопасить и всегда выделять массивы в общей памяти независимо от их размера.
double x[268435448]; в общем разделе компилируется.
268435449 - уже не компилируется
А в OnStart() скрипта 268435449 компилируется, причем в общем разделе оставил этот громадный массив x.
268435448*8=2 147 483 584 - это два гига.
***
А вот предел в функции: double x[268435456];
Это ограничения анализатора кода. Ведь нет на самом деле ни каких проблем выделить ни 4 ни 6 ни 20 Гб памяти в mql, если она есть.
всегда выделять массивы в общей памяти независимо от их размера.
Не использовать статические массивы?