Ошибки, баги, вопросы - страница 1437

 
Ilyas:
Поведение разное, из-за более агрессивного оптимизатора для MQL5 кода.
А ещё МТ4 оказался умнее и выдал предупреждение "integral constant overflow", а МТ5 промолчал.
 
Ilya Malev:

1. Почему в МТ4 и в МТ5 этот код приводит к разному результату (причем в МТ4 к более логичному)?

Читайте документацию

Чему равно EMPTY_VALUE в MQL4?

Прочие константы - Документация на MQL4
  • docs.mql4.com
Прочие константы - Документация на MQL4
 
Сергей Таболин:

Подскажите почему выдаёт ошибку "вне диапозона" следующая строка (при первом обращении):

Объявить - объявили, а кто будет заполнять буфер buf_ldn[ldn]? 
 
Сергей Таболин:

Посмотрите, какие значения у pr_open и pr_close при первом обращении к ним.
 
Сергей Таболин:

так ведь это и есть заполнение:

или я чего-то не догнал?

Вы массив объявили, а размер массива не указали ...

Статический пример int            buf_lup[1000], buf_ldn[20000]; 

 
Сергей Таболин:

так ведь это и есть заполнение:

или я чего-то не догнал?

Не, это не заполнение массива. К тому же если ldn = 0; то подставляя 0 в [ ] вы объявили 0 элементов в массиве, т.е. там нет ни одного элемента даже. О массивах читайте статью Основы программирования на MQL5 - Массивы.
 
Сергей Таболин:

так ведь это и есть заполнение:

или я чего-то не догнал?

Перед заполнением нужно массиву задать размер. (ArrayRezise). Простой пример:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2015, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property script_show_inputs
input bool show_error=true; // true - выполнить с ишибкой
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int buf_ldn[]; // объявили динамический массив.
   Print("Размер массива buf_ldn[]=",ArraySize(buf_ldn)); // выведем на печать размер массива
   if(show_error)
     {
      //--- попытка присвоить значение элементу массива с индексом "0" вызовет ошибку:
      //--- Test (EURUSD,M15)   array out of range in 'Test.mq5' (22,14)
      buf_ldn[0]=1;
     }
   else
     {
      //--- установим новый размер массива:
      ArrayResize(buf_ldn,1);
      //--- попытка присвоить значение элементу массива с индексом "0" НЕ вызовет ошибку:
      buf_ldn[0]=1;
      //--- выведем на печать размер массива и значение элемента с индексом "0"
      Print("Размер массива buf_ldn[]=",ArraySize(buf_ldn),", элемент с индексом ""0"" имеет значение:",buf_ldn[0]);
     }
  }
//+------------------------------------------------------------------+
Файлы:
Test.mq5  2 kb
 
Сергей Таболин:

А когда вопрос с размером массива разрешится, всё-таки, полагаю, стоит посмотреть, какие значения у pr_open и pr_close при первом обращении к ним.


P./S.: Тут они не проинициализированы:

...
int            buf_lup[], buf_ldn[];
...
void OnTick()
{
   int      lup, ldn, sup, sdn;
   int      sum_up, sum_dn;
   double   pr_open, pr_close;

.........

      ldn = 0;
      sup = 0;
      sdn = 0;
      sum_up = 0;
      sum_dn = 0;

.........

               buf_ldn[ldn] = (int)((pr_open - pr_close) / Point()); // ОШИБКА тут
               sum_dn += buf_ldn[ldn++];

........
}

и не видно в коде, чтобы им что-то присваивалось.

Хотя может их инициализация где-то в этих:

.........

строчках кода спрятана у вас.

 
Сергей Таболин:

Именно ))) В них проблемм нет.

А вообще, как-то это неудобно постоянно следить за размерностью динамического массива...  Нужно знать сколько он весит. А смысл тогда в нём какой? ....

Смысл в нём такой, что если заранее неизвестно количество элементов, которые в него будут помещены, не нужно объявлять статический массив гарантированно большего размера (с большим запасом, чтобы на все случаи жизни хватило) и понапрасну расходовать память. Просто по мере появления новых данных, которые нужно добавить в массив, динамически увеличиваете его размер.
 
Сергей Таболин:

В принципе, это понятно. Не понятно только почему нельзя увеличивать этот массив автоматически?

Ну вот почему так нельзя было сделать? Это не я придумал ))) Именно так я и пытался использовать динамический массив...

Плюс дополнительно нужно индекс сохранять... Не фонтан... 

Кто сказал что нельзя увеличить динамически ???

Вот Вам в помощь

ArrayResize

Устанавливает новый размер в первом измерении массива



int  ArrayResize( 
   void&  array[],              // массив, переданный по ссылке 
   int    new_size,             // новый размер массива 
   int    reserve_size=0        // резервное значение размера (избыточное) 
   );
 

Параметры

array[]

[out]  Массив для изменения размеров.

new_size

[in]  Новый размер для первого измерения.

reserve_size=0

[in]  Необязательный параметр. Размер для дополнительного резерва.

Возвращаемое значение

При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры.

Примечание

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

Общее число элементов в массиве не может превышать 2147483647.

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



ArrayResize(arr,1000,1000); 
for(int i=1;i<3000;i++) 
   ArrayResize(arr,i,1000);
 

В данном случае произойдёт 2 перераспределения памяти, один раз до входа в цикл на 2000 элементов, при этом размерность массива будет установлена в 1000 и второй при i равной 2000. Если третий параметр опустить, то произойдёт 2000 физических перераспределения памяти и это замедлит выполнение программы.

 

Надо сделать справку о том как пользоваться справкой )))))))))))))))))))))