Новая версия платформы MetaTrader 5 build 5370: улучшения в веб-версии - страница 10

 
fxsaber # :

После запуска этого скрипта .


Спасибо, воспроизвел.

 
Эти функции не работают в тестере стратегий в визуальном режиме.
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  { 
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    
   ChartSetInteger(0,CHART_SHOW_DATE_SCALE,false);    // function not working in Strategy Tester
   ChartSetInteger(0,CHART_SHOW_PRICE_SCALE,false);   // function not working in Strategy Tester
   ChartSetInteger(0,CHART_SCALEFIX,true);            // function not working in Strategy Tester
   ChartSetDouble(0,CHART_FIXED_MAX,bid+bid*0.01);    // function not working in Strategy Tester
   ChartSetDouble(0,CHART_FIXED_MIN,bid-bid*0.01);    // function not working in Strategy Tester

   ChartRedraw();
      
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    
   ChartSetInteger(0,CHART_SHOW_DATE_SCALE,false);    // function not working in Strategy Tester
   ChartSetInteger(0,CHART_SHOW_PRICE_SCALE,false);   // function not working in Strategy Tester
   ChartSetInteger(0,CHART_SCALEFIX,true);            // function not working in Strategy Tester
   ChartSetDouble(0,CHART_FIXED_MAX,bid+bid*0.01);    // function not working in Strategy Tester
   ChartSetDouble(0,CHART_FIXED_MIN,bid-bid*0.01);    // function not working in Strategy Tester
   
   ChartRedraw();
  }
//+------------------------------------------------------------------+

Также в тестере стратегий при открытии настроек (F8) те же функции не действуют.

функции не действуют

 

b5370, в некоторых случаях написание входного параметра макроса вызывает тормоза в ME.

#include <fxsaber\TesterCache\TesterCache.mqh> // https://www.mql5.com/ru/code/26223

#define MACROS(A)

MACROS(.sdfkjsdfkjkljsdfkljsdfkljhsdfkljhdjsfksd) // После точки набор текста тормозит в ME.
MACROS(dkjsfkljhsdfldskjdklsfjhdfbghjkbdgfvjxchb) // Без точки набор текста не тормозит в ME.

Почему это связано с библиотекой - не знаю. Просьба исправить.

Строка для поиска: Uluchshenie 143.
 
fxsaber #:

b5370, в некоторых случаях написание входного параметра макроса вызывает тормоза в ME.

Почему это связано с библиотекой - не знаю. Просьба исправить.

Строка для поиска: Uluchshenie 143.

Не могу понять норма это или нет?

При компиляции вылетает 

2025.11.05 13:08:21.803 testst (EURUSD,H1)      2 undeleted dynamic objects found:
2025.11.05 13:08:21.803 testst (EURUSD,H1)         1 object of class 'B'
2025.11.05 13:08:21.803 testst (EURUSD,H1)         1 object of class 'A'
2025.11.05 13:08:21.803 testst (EURUSD,H1)      96 bytes of leaked memory found

Но при обычной работе эксперта, переключения таймфреймов, изменения настроек робота, ошибки нет.

Ошибка только при компиляции.

//+------------------------------------------------------------------+
//|                                                       testst.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
class A
  {
public:
   void              func(void) {};
                     A(void) {};
                    ~A(void) {};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class B
  {
protected:

public:
   void              func(void) {};
   A                 *Z;
                     B(void);
                    ~B(void);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
B::B(void)
  {
   Z = new A();
   ::Print(GetLastError());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
B::~B(void)
  {
  ::Print(GetLastError());
   if(Z)
     {
     ::Print(GetLastError());
      delete Z;
      Z = NULL;
     }
     ::Print(GetLastError());
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   B * b = new B;
::Print(GetLastError());

b.func();

::Print(GetLastError());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

  }
//+------------------------------------------------------------------+
 
Vladimir Pastushak #:

Не могу понять норма это или нет?

При компиляции вылетает 

Но при обычной работе эксперта, переключения таймфреймов, изменения настроек робота, ошибки нет.

Ошибка только при компиляции.

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

При перекомпиляции - советник, естественно, переинициализируется. Соответственно, и объекты-потеряшки появляются. Но, если в OnDeinit() советника добавить delete b, то потеряшек не будет.

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

 
Artyom Trishkin #:

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

При перекомпиляции - советник, естественно, переинициализируется. Соответственно, и объекты-потеряшки появляются. Но, если в OnDeinit() советника добавить delete b, то потеряшек не будет.

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

Да спасибо я это понимаю.

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

Разве компиляция не должна работать последовательно и очищать правильно все данные ?
 
Vladimir Pastushak #:

Да спасибо я это понимаю.

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

Деструктор должен вызываться при снятии программы с графика - так и проверять нужно - запустив советник, снять его с графика. Но у Вас нет удаления объекта при деинициализации. Отсюда и потеряшка - не вызывается деструктор. Так же деструкторы должны срабатывать при delete объекта.

В общем решение простое - всегда должна быть пара new - delete.

 
Vladimir Pastushak #:
Разве компиляция не должна работать последовательно и очищать правильно все данные ?

При перекомпиляции программа снимается с графика. Всё и работает последовательно:

  • У нас есть созданный объект где-то в памяти, и есть на него указатель b. По этому указателю мы и работаем с этим объектом.
  • При снятии программы с графика или перекомпиляции срабатывает OnDeinit(). Но он пустой. Программа удаляется из памяти, а созданный объект - нет (нет же в коде delete b)
  • Неудалённый объект остаётся занимать память - утечка.
 
Artyom Trishkin #:

При перекомпиляции программа снимается с графика. Всё и работает последовательно:

  • У нас есть созданный объект где-то в памяти, и есть на него указатель b. По этому указателю мы и работаем с этим объектом.
  • При снятии программы с графика или перекомпиляции срабатывает OnDeinit(). Но он пустой. Программа удаляется из памяти, а созданный объект - нет (нет же в коде delete b)
  • Неудалённый объект остаётся занимать память - утечка.

Благодарю.

Тогда почему при пустом OnDeinit() при смене ТаймФрейма не вылетает эта же ошибка ?

Почему при смене ТаймФрейма деинициализачия и деструкторы отрабатываею верно, а при компиляции нет ?

Я всё таки склоняюсь к багу компилятора, который при перекомпиляции программы не правильно уничтожает обьекты.
 
Vladimir Pastushak #:
Тогда почему при пустом OnDeinit() при смене ТаймФрейма не вылетает эта же ошибка ?

Это же советник?

Так он не снимается с графика при смене периода графика. Утечка памяти происходит только тогда, когда программа прекращает работу и снимается с графика.