Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 167

 
Igor Makanu:

dachten Sie nicht, dass Sie Probleme haben würden, den Kurzcode zu lesen, dann lesen Sie die Hilfehttps://www.mql5.com/ru/docs/trading/ordercalcmargin

Danke, ich habe es schon herausgefunden)

Ich habe gerade angefangen, MQL5 zu lernen. Ich muss meine Frage an einer falschen Stelle gestellt haben.

 
Plattformübergreifender Unterschied 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:
Plattformübergreifender Unterschied ArrayCopy.

Um keinen Unterschied zu machen, müssen Sie natürlich schreiben

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

entweder

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

oder alle Standardwerte in diesem Zusammenhang

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

Um keinen Unterschied zu machen, müssen Sie natürlich schreiben

entweder

oder alle Standardwerte in diesem Zusammenhang

Hier ist das Problem.

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

Wenn die Funktion Null zurückgibt, haben MQL4 und MQL5 unterschiedliche Ergebnisse.

 
fxsaber:

Hier liegt das Problem.

Wenn die Funktion Null zurückgibt, werden MQL4 und MQL5 unterschiedliche Ergebnisse liefern.

GetAmountToCopy() löst also dieses Problem, falls die Funktion Null zurückgeben sollte.

Zum Beispiel:

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

Hier liegt das Problem.

Wenn die Funktion Null zurückgibt, werden MQL4 und MQL5 unterschiedliche Ergebnisse liefern.

Es ist nicht ganz klar, was Sie da ausrechnen. Es kann mehrere Varianten der Rückgabe von GetAmountToCopy() geben.

Wenn 0 bedeutet, dass nichts kopiert wird (das ist die Bedingung, die meiner Meinung nach das Problem verursacht) und -1 bedeutet, dass das gesamte Array kopiert wird, sollten Sie natürlich andere Rückgabewerte als 0 und -1 angeben, falls Sie nichts kopieren wollen. Zum Beispiel: EMPTY_VALUE zurückgeben. In diesem Fall sollten wir wahrscheinlich die Funktion ArrayCopy() überladen, die zunächst prüft, was ihr von GetAmountToCopy() übergeben wurde. Wenn es EMPTY_VALUE ist, wird die Funktion verlassen. Im Übrigen wird bei Verwendung der Konstante WHOLE_ARRAY die Größe der zu kopierenden Daten sowohl in MQL5 als auch in MQL4 korrekt ausgewählt.

 
Artyom Trishkin:

Es ist nicht ganz klar, was Sie da ausrechnen.

Es ist mir nicht ganz klar, warum Sie über mögliche Implementierungen von MQL4/5-Unterschieden schreiben. Ich habe diese Unterschiede nur für diejenigen festgestellt, die plattformübergreifenden Code schreiben.

Die Unterschiede haben sich bereits zu einem Artikel verdichtet. Jemand sollte es schreiben.

 
fxsaber:

Ich bin mir nicht ganz sicher, warum Sie über mögliche Umgehungen der MQL4/5-Unterschiede schreiben. Ich habe diese Unterschiede nur für diejenigen festgestellt, die plattformübergreifenden Code schreiben.

Die Unterschiede haben sich bereits zu einem Artikel verdichtet. Jemand sollte es schreiben.

Ich dachte, es sei eine Frage. Gut. Ich kann meine Nachrichten löschen.

 

Bisher nur vermutet, jetzt bestätigt. Bei der Arbeit mit Ressourcen kann es leicht zu Speicherlecks kommen.


Beispiel.

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


Ein Skript über SB gibt einen Graphen eines numerischen Arrays in einem Diagramm aus. Sie können dieses Diagramm (Objekt) dann manuell löschen, aber die diesem Diagramm zugewiesene Ressource bleibt für immer im Speicher im Nur-Lese-Modus hängen. Sie kann nicht gelöscht werden, da nur das Eigentümer-Skript sie löschen kann (siehe die hervorgehobene Zeile).


Es gibt keine Funktion in MQL, um so belegten Speicher freizugeben. Seien Sie damit auf VPS besonders vorsichtig.

 
fxsaber:

Bisher nur vermutet, jetzt bestätigt. Bei der Arbeit mit Ressourcen kann es leicht zu Speicherlecks kommen.


Beispiel.


Ein Skript über SB gibt einen Graphen eines numerischen Arrays in einem Diagramm aus. Sie können dieses Diagramm (Objekt) dann manuell löschen, aber die diesem Diagramm zugewiesene Ressource bleibt für immer im Speicher im Nur-Lese-Modus hängen. Sie kann nicht gelöscht werden, da nur das Eigentümer-Skript sie löschen kann (siehe die hervorgehobene Zeile).


Es gibt keine Funktion in MQL, um so belegten Speicher freizugeben. Seien Sie bei VPS besonders vorsichtig.

Wenn Sie eine Meldung über ein Speicherleck erhalten, bedeutet dies, dass es keinen expliziten Befehl zur Freigabe dieses Speichers gab.

Wenn ein Programm beendet wird (das ist der Zeitpunkt, an dem Sie diese Meldungen erhalten), gibt es den gesamten Speicher frei, einschließlich des ausgelaufenen Speichers.

Grund der Beschwerde: