Особенности языка mql5, тонкости и приёмы работы - страница 167

 
Igor Makanu:

не думал, что у Вас будут сложности в чтении короткого кода, тогда читайте справку https://www.mql5.com/ru/docs/trading/ordercalcmargin

Спасибо, уже разобралась )

Я только начала изучать MQL5. Наверное не в ту ветку вопрос задала

 
Кроссплатформенная разница ArrayCopy.
#property strict

void OnStart()
{
  int Array1[1];
  int Array2[1];
  
  Print(ArrayCopy(Array1, Array2, 0, 0, 0)); // MQL4 - 1, MQL5 - 0
  Print(WHOLE_ARRAY); // MQL4 - 0, MQL5 - -1
}
 
fxsaber:
Кроссплатформенная разница ArrayCopy.

Очевидно, чтобы не было разницы, нужно писать

  Print(ArrayCopy(Array1, Array2, 0, 0, WHOLE_ARRAY));

или

Print(ArrayCopy(Array1, Array2, 0, 0));

или всё по умолчанию в данном контексте

Print(ArrayCopy(Array1, Array2));
 
Artyom Trishkin:

Очевидно, чтобы не было разницы, нужно писать

или

или всё по умолчанию в данном контексте

Здесь проблема.

ArrayCopy(Array1, Array2, 0, 0, GetAmountToCopy());

Если функция вернет ноль, то MQL4 и MQL5 будут с разным результатом.

 
fxsaber:

Здесь проблема.

Если функция вернет ноль, то MQL4 и MQL5 будут с разным результатом.

Значит в GetAmountToCopy() эту проблему и решать в случае, если функция должна вернуть ноль.

Например:

return(res==0 ? WHOLE_ARRAY : res);
 
fxsaber:

Здесь проблема.

Если функция вернет ноль, то MQL4 и MQL5 будут с разным результатом.

Тут не очень понятно что вы там рассчитываете. Вариантов возврата из GetAmountToCopy() может быть несколько.

Если 0 - ничего не копировать (именно это условие создаёт проблему как я понял), а -1 - копировать весь массив, то очевидно, нужно задать возвращаемые величины, отличные от 0 и -1 в случае, если нужно ничего не копировать. Например, возвращать EMPTY_VALUE. В этом случае нужно сделать наверное перегруженную функцию ArrayCopy(), которая сначала проверит что передано в неё из GetAmountToCopy(). Если EMPTY_VALUE, то выходить из функции. В остальном, при использовании константы WHOLE_ARRAY, будет правильно выбран размер копируемых данных и в MQL5, и в MQL4.

 
Artyom Trishkin:

Тут не очень понятно что вы там рассчитываете.

Мне не совсем понятно, для чего Вы пишите о возможных реализациях обхода различия MQL4/5. Я только отметил эти отличия для тех, кто пишет кроссплатформенный код.

Отличий уже на статью накопилось... Написал бы кто-нибудь.

 
fxsaber:

Мне не совсем понятно, для чего Вы пишите о возможных реализациях обхода различия MQL4/5. Я только отметил эти отличия для тех, кто пишет кроссплатформенный код.

Отличий уже на статью накопилось... Написал бы кто-нибудь.

Мне показалось, что это был вопрос. Добро. Могу удалить свои сообщения.

 

Раньше только подозревал, теперь подтвердилось. При работе с ресурсами легко получить утечку памяти.


Пример.

#include <Graphics\Graphic.mqh>

#define MIN_WIDTH 10

// Создание графика.
string GraphPlot( const double &Y[],
                  int Width = 0, int Height = 0, const ENUM_CURVE_TYPE Type = CURVE_NONE,
                  const string CurveName = NULL, string ObjName = NULL )
{
  Width = Width ? Width : (int)::ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
  Height = Height ? Height : (int)::ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
  ObjName = (ObjName == NULL) ? __FUNCTION__ : ObjName;

  CGraphic Graphic;

  const bool Res = (::ObjectFind(0, ObjName) >= 0) ? Graphic.Attach(0, ObjName) : Graphic.Create(0, ObjName, 0, 0, 0, Width, Height);

  if (Res)
  {
    const int Size = ::ArraySize(Y);

    Graphic.CurveAdd(Y, ((Type == CURVE_NONE) && Size) ? ((Width / Size < MIN_WIDTH) ? CURVE_LINES : CURVE_POINTS_AND_LINES) : Type, CurveName);

    Graphic.CurvePlotAll();
    Graphic.Update();
  }

  return (Res ? Graphic.ChartObjectName() : NULL);
}

void OnStart()
{  
  const double Array[] = {0, 1, 2, 3, 4, 5};
      
  const string ObjName = GraphPlot(Array, 1200); // Создали график-объект.
  const string ResourceName = ::ObjectGetString(0, ObjName, OBJPROP_BMPFILE); // К какому ресурсу привязка объекта.
  
  // ObjectDelete(0, ObjName); // Удалили объект.

//  ResourceFree(StringSubstr(ResourceName, StringFind(ResourceName, "::"))); // Без этой строки утечка памяти.
}


Скрипт через СБ выводит график числового массива на чарт. Вы можете потом руками удалить этот график (объект), но ресурс, закрепленный за этим графиком, останется висеть навсегда в памяти в режиме read-only. Его нельзя будет удалить, т.к. удалять его может (см. выделенную строку) только скрипт-хозяин.


В MQL отсутствует функционал для высвобождения так занятой памяти. Будьте с этим особенно аккуратны на VPS.

 
fxsaber:

Раньше только подозревал, теперь подтвердилось. При работе с ресурсами легко получить утечку памяти.


Пример.


Скрипт через СБ выводит график числового массива на чарт. Вы можете потом руками удалить этот график (объект), но ресурс, закрепленный за этим графиком останется висеть навсегда в памяти в режиме read-only. Его нельзя будет удалить, т.к. удалять его может (см. выделенную строку) только скрипт-хозяин.


В MQL отсутствует функционал для высвобождения так занятой памяти. Будьте особенно аккуратны на VPS.

Когда Вы получаете сообщение об утечке памяти, это означает, что не было явной команды освобождения этой памяти.

Когда программа завершает работу (а именно на завершении работы Вы получаете такие сообщения), то она в любом случае освобождает всю память, в том числе утёкшую.

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