Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 167

 
Igor Makanu:

non pensavi di avere problemi a leggere il codice breve, allora leggi l'aiutohttps://www.mql5.com/ru/docs/trading/ordercalcmargin

Grazie, l'ho già capito )

Ho appena iniziato a imparare MQL5. Devo aver messo la mia domanda in un posto sbagliato

 
Differenza multipiattaforma 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:
Differenza multipiattaforma ArrayCopy.

Ovviamente, per non fare alcuna differenza, bisogna scrivere

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

o

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

o tutti i default in questo contesto

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

Ovviamente, per non fare alcuna differenza, bisogna scrivere

o

o tutti i default in questo contesto

Ecco il problema.

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

Se la funzione restituisce zero, allora MQL4 e MQL5 avranno risultati diversi.

 
fxsaber:

Ecco il problema.

Se la funzione restituisce zero, MQL4 e MQL5 avranno risultati diversi.

Quindi, GetAmountToCopy() risolve questo problema nel caso in cui la funzione dovesse restituire zero.

Per esempio:

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

Ecco il problema.

Se la funzione restituisce zero, MQL4 e MQL5 avranno risultati diversi.

Non è del tutto chiaro cosa state calcolando lì. Ci possono essere diverse varianti di ritorno da GetAmountToCopy().

Se 0 è per non copiare nulla (questa è la condizione che causa il problema per come la vedo io) e -1 è per copiare l'intero array, dovreste ovviamente specificare valori di ritorno diversi da 0 e -1 nel caso in cui vogliate non copiare nulla. Per esempio, restituisce EMPTY_VALUE. In questo caso dovremmo probabilmente sovraccaricare la funzione ArrayCopy() che prima controllerà ciò che le viene passato da GetAmountToCopy(). Se è EMPTY_VALUE, allora uscite dalla funzione. Per il resto, se si usa la costante WHOLE_ARRAY, la dimensione dei dati da copiare sia in MQL5 che in MQL4 sarà selezionata correttamente.

 
Artyom Trishkin:

Non è molto chiaro cosa stai calcolando lì.

Non mi è molto chiaro perché stai scrivendo sulle possibili implementazioni delle differenze MQL4/5. Ho appena notato queste differenze per coloro che scrivono codice multipiattaforma.

Le differenze si sono già accumulate per un articolo. Qualcuno dovrebbe scriverlo.

 
fxsaber:

Non ho ben capito perché stai scrivendo di possibili workaround alle differenze MQL4/5. Ho appena notato queste differenze per coloro che scrivono codice multipiattaforma.

Le differenze si sono già accumulate per un articolo. Qualcuno dovrebbe scriverlo.

Pensavo fosse una domanda. Bene. Posso cancellare i miei messaggi.

 

Prima solo sospettato, ora confermato. È facile avere perdite di memoria quando si lavora con le risorse.


Esempio.

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


Uno script via SB stampa un grafico di un array numerico su un grafico. Potete quindi cancellare manualmente questo grafico (oggetto), ma la risorsa assegnata a questo grafico rimarrà per sempre sospesa in memoria in modalità di sola lettura. Non può essere cancellato, perché solo lo script proprietario può cancellarlo (vedi la linea evidenziata).


Non c'è nessuna funzionalità in MQL per liberare la memoria così occupata. State particolarmente attenti con questo su VPS.

 
fxsaber:

Prima solo sospettato, ora confermato. È facile avere perdite di memoria quando si lavora con le risorse.


Esempio.


Uno script via SB stampa un grafico di un array numerico su un grafico. Potete quindi cancellare manualmente questo grafico (oggetto), ma la risorsa assegnata a questo grafico rimarrà per sempre sospesa in memoria in modalità di sola lettura. Non può essere cancellato, perché solo lo script proprietario può cancellarlo (vedi la linea evidenziata).


Non c'è nessuna funzionalità in MQL per liberare la memoria così occupata. Siate particolarmente attenti sui VPS.

Quando si riceve un messaggio su una perdita di memoria, significa che non c'era un comando esplicito per liberare quella memoria.

Quando un programma termina (che è quando si ottengono questi messaggi), in ogni caso libererà tutta la memoria, compresa quella persa.