Características del lenguaje mql5, sutilezas y técnicas - página 167

 
Igor Makanu:

no creía que tuviera problemas para leer el código corto, entonces lea la ayudahttps://www.mql5.com/ru/docs/trading/ordercalcmargin

Gracias, ya lo he averiguado )

Acabo de empezar a aprender MQL5. Debo haber puesto mi pregunta en un lugar equivocado

 
Diferencia entre plataformas 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:
Diferencia entre plataformas ArrayCopy.

Obviamente, para que no haya diferencia, hay que escribir

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

o bien

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

o todo por defecto en este contexto

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

Obviamente, para que no haya diferencia, hay que escribir

o bien

o todo por defecto en este contexto

Este es el problema.

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

Si la función devuelve cero, entonces MQL4 y MQL5 tendrán resultados diferentes.

 
fxsaber:

Este es el problema.

Si la función devuelve cero, MQL4 y MQL5 tendrán resultados diferentes.

Así, GetAmountToCopy() resuelve este problema en caso de que la función devuelva cero.

Por ejemplo:

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

Este es el problema.

Si la función devuelve cero, MQL4 y MQL5 tendrán resultados diferentes.

No está muy claro lo que está calculando ahí. Puede haber varias variantes de retorno de GetAmountToCopy().

Si 0 es no copiar nada (esta es la condición que causa el problema, según tengo entendido) y -1 es copiar todo el array, obviamente debes especificar valores de retorno distintos de 0 y -1 en caso de que quieras no copiar nada. Por ejemplo, devuelve EMPTY_VALUE. En este caso probablemente deberíamos sobrecargar la función ArrayCopy() que primero comprobará lo que se le pasa desde GetAmountToCopy(). Si es EMPTY_VALUE, se sale de la función. Por lo demás, si se utiliza la constante WHOLE_ARRAY, se seleccionará correctamente el tamaño de los datos a copiar tanto en MQL5 como en MQL4.

 
Artyom Trishkin:

No está muy claro lo que estás calculando ahí.

No me queda muy claro por qué escribes sobre las posibles implementaciones de las diferencias de MQL4/5. Acabo de anotar estas diferencias para los que escriben código multiplataforma.

Las diferencias ya se han acumulado para un artículo. Alguien debería escribirlo.

 
fxsaber:

No sé muy bien por qué escribes sobre posibles soluciones a las diferencias de MQL4/5. Acabo de anotar estas diferencias para los que escriben código multiplataforma.

Las diferencias ya se han acumulado para un artículo. Alguien debería escribirlo.

Pensé que era una pregunta. Bien. Puedo borrar mis mensajes.

 

Antes sólo se sospechaba, ahora se confirma. Es fácil tener fugas de memoria cuando se trabaja con recursos.


Ejemplo.

#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, "::"))); // Без этой строки утечка памяти.
}


Un script a través de SB imprime una gráfica de un array numérico en un gráfico. A continuación, puede eliminar manualmente este gráfico (objeto), pero el recurso asignado a este gráfico permanecerá para siempre colgado en la memoria en modo de sólo lectura. No puede ser borrado, porque sólo el script propietario puede borrarlo (ver la línea resaltada).


No hay ninguna funcionalidad en MQL para liberar la memoria tan ocupada. Tenga especial cuidado con esto en VPS.

 
fxsaber:

Antes sólo se sospechaba, ahora se confirma. Es fácil tener fugas de memoria cuando se trabaja con recursos.


Ejemplo.


Un script a través de SB imprime una gráfica de un array numérico en un gráfico. A continuación, puede eliminar manualmente este gráfico (objeto), pero el recurso asignado a este gráfico permanecerá para siempre colgado en la memoria en modo de sólo lectura. No puede ser borrado, porque sólo el script propietario puede borrarlo (ver la línea resaltada).


No hay ninguna funcionalidad en MQL para liberar la memoria tan ocupada. Tenga especial cuidado con los VPS.

Cuando se recibe un mensaje sobre una fuga de memoria, significa que no hubo un comando explícito para liberar esa memoria.

Cuando un programa termina (que es cuando se reciben estos mensajes), libera toda la memoria, incluida la memoria filtrada, en cualquier caso.

Razón de la queja: