Непонятная ошибка, может вообще к разработчику обращаться

 

Есть такой код в индикаторе 

if(MODE == First) limit = rates_total-1;

  else limit = rates_total-prev_calculated;

 //--- main loop      

  for(int i=limit; i>0; i--){

    H1_sh = iBarShift(NULL,PERIOD_H1,time[i]);


В последней строке произошла ошибка ARRAY OUT OF RANGE. Как говорится чтобы это было?


РЕШЕНО!!! Иногда теминал сам обнуляет prev_calculated (в частности при обновлении истории) - обязательна проверка этой переменной. Или используйте время последнего обработанного бара для определения количества необработанных баров. 


А вот такая штука кому-нить чего-нить говорит?

2019.09.11 13:29:21.288 Custom indicator ZigZagYA EURUSD,M1: removed

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 16492 bytes of leaked memory

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 4 leaked strings left

2019.09.11 13:29:21.284 ZigZagYA EURUSD,M1: uninit reason 1

Вроде как при удалении индюка с графика он сам освобождает память всех переменных или все же нет? 

 
Aleksandr Martynov:

Есть такой код в индикаторе 

if(MODE == First) limit = rates_total-1;

  else limit = rates_total-prev_calculated;

 //--- main loop      

  for(int i=limit; i>0; i--){

    H1_sh = iBarShift(NULL,PERIOD_H1,time[i]);


В последней строке произошла ошибка ARRAY OUT OF RANGE. Как говорится чтобы это было?

А вот такая штука кому-нить чего-нить говорит?

2019.09.11 13:29:21.288 Custom indicator ZigZagYA EURUSD,M1: removed

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 16492 bytes of leaked memory

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 4 leaked strings left

2019.09.11 13:29:21.284 ZigZagYA EURUSD,M1: uninit reason 1

Вроде как при удалении индюка с графика он сам освобождает память всех переменных или все же нет? 

попробуйте строку

  else limit = rates_total-prev_calculated;

заменить на

  else limit = rates_total-prev_calculated - 1;

 
Aleksandr Martynov:

if(MODE == First) limit = rates_total-1;

  else limit = rates_total-prev_calculated;

 //--- main loop      

  for(int i=limit; i>0; i--){

    H1_sh = iBarShift(NULL,PERIOD_H1,time[i]);

В последней строке произошла ошибка ARRAY OUT OF RANGE. Как говорится чтобы это было?

Получение данных с H1, индикатор вероятно на другом тф.
Ещё, time[i] может выдавать эту ошибку если данные текущего тф не готовы:
if(rates_total<1) return(0);//нужная проверка

А вот такая штука кому-нить чего-нить говорит?

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 16492 bytes of leaked memory

Течёт память.
при удалении индюка с графика он сам освобождает память всех переменных - да, но таки например:

Объект, созданный с помощью оператора new, должен быть явно уничтожен оператором delete. ©
 
Aleksandr Martynov:

...

А вот такая штука кому-нить чего-нить говорит?

2019.09.11 13:29:21.288 Custom indicator ZigZagYA EURUSD,M1: removed

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 16492 bytes of leaked memory

2019.09.11 13:29:21.286 ZigZagYA EURUSD,M1: 4 leaked strings left

2019.09.11 13:29:21.284 ZigZagYA EURUSD,M1: uninit reason 1


Можете предоставить исходный код индикатора ZigZagYA для изучения ?

После всех проверок я его удалю
 
Aleksey Lebedev:

Получение данных с H1, индикатор вероятно на другом тф.
Ещё, time[i] может выдавать эту ошибку если данные текущего тф не готовы:
if(rates_total<1) return(0);//нужная проверка

Течёт память.
при удалении индюка с графика он сам освобождает память всех переменных - да, но таки например:

Объект, созданный с помощью оператора new, должен быть явно уничтожен оператором delete. ©

Спасибо, за ответ! Последний вопрос - я использую только динамические массивы, никаких объектов, по крайней мере в явном виде

Данные текущего ТФ не могут быть не готовы, так как тик приходит на текущем ТФ, более того как видно из кода я обрабатываю только сформировавшийся бар (i>0). 

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

 
Ilyas:
Можете предоставить исходный код индикатора ZigZagYA для изучения ?

После всех проверок я его удалю

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

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

 
Aleksandr Martynov:

Данные текущего ТФ не могут быть не готовы, так как тик приходит на текущем ТФ, более того как видно из кода я обрабатываю только сформировавшийся бар (i>0). 

Дело не в том, что данные не готовы, а в том, что обращение идет к несуществующему бару. К примеру, запускаете индикатор и после первого тика значение MODE становится не First. То есть на следующей итерации переменная limit примет значение rates_total-prev_calculated. Ошибка в том, что нет проверки значения prev_calculated. Оно может быть равно нулю не только при первом запуске, но и в середине работы (докачка данных). В итоге limit становится равным rates_total, а такого бара нет.

Поэтому нужно проверять значение prev_calculated на равенство нулю и в этом случае уменьшать значение limit на 1.

 

Вся загвоздка в том, что ошибка в размере массива, кроме массива time[] в этой строке нет ничего, цикл фор просто не пустит при отрицательном значении i, функция iBarShift возвращает -1, если не смогла найти время указанное в параметрах и ошибка должна быть в другой строке.

Ошибка образовалась в течении 2 секунды от начала бара, я понимаю, что могло быть отсутствие канала и все такое на переходе бара, но код говорит, что при расчете текущего бара может быть только количество пропущенных баров, 1 при переходе к новому бару или 0 для текущего, в таймсерии time[] эти значения по любому существуют, даже если они не обновились.

Есть подозрение, что из-за ограничения количества баров в истории произошло стирание истории - следовательно изменилось общее количество баров, а из последнего вызова ОнТик было передано предыдущее количество баров. НО!!!! блин предыдущее по умолчанию больше и поэтому в цикле по отрицательному лимит ничего не должно делаться.

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

 
Ihor Herasko:

Дело не в том, что данные не готовы, а в том, что обращение идет к несуществующему бару. К примеру, запускаете индикатор и после первого тика значение MODE становится не First. То есть на следующей итерации переменная limit примет значение rates_total-prev_calculated. Ошибка в том, что нет проверки значения prev_calculated. Оно может быть равно нулю не только при первом запуске, но и в середине работы (докачка данных). В итоге limit становится равным rates_total, а такого бара нет.

Поэтому нужно проверять значение prev_calculated на равенство нулю и в этом случае уменьшать значение limit на 1.

это произошло через 13 часов работы индикатора на минутке и почему соседний индикатор, который также обращается к минутному ТФ этой ошибки не получил?

прев_кальк - определяется насколько я понимаю return(rates_total)? В этом случае при догрузке данных вы все равно знаете сколько было обработано баров. Разве не так по смыслу?

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

 
Ihor Herasko:

Дело не в том, что данные не готовы, а в том, что обращение идет к несуществующему бару. К примеру, запускаете индикатор и после первого тика значение MODE становится не First. То есть на следующей итерации переменная limit примет значение rates_total-prev_calculated. Ошибка в том, что нет проверки значения prev_calculated. Оно может быть равно нулю не только при первом запуске, но и в середине работы (докачка данных). В итоге limit становится равным rates_total, а такого бара нет.

Поэтому нужно проверять значение prev_calculated на равенство нулю и в этом случае уменьшать значение limit на 1.

ОнТик у меня вне зависимости от исхода возвращает количество баров текущее и, действительно, переменная MODE = First только при первом проходе после инициализации. за этот проход рассчитывается вся история и потом меня интересуют только новые сформировавшиеся бары

 
Aleksandr Martynov:

это произошло через 13 часов работы индикатора на минутке и почему соседний индикатор, который также обращается к минутному ТФ этой ошибки не получил?

Разные окна графиков...

прев_кальк - определяется насколько я понимаю return(rates_total)? В этом случае при догрузке данных вы все равно знаете сколько было обработано баров. Разве не так по смыслу?

Да, плюс терминал сам может изменить значение prev_calculated, если оно окажется бОльшим, чем количество измененных баров. Ошибка явная. Для подтверждения посмотрите код примера для в функции IndicatorCounted(). Там как раз есть такая проверка.

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