Caractéristiques du langage mql5, subtilités et techniques - page 167

 
Igor Makanu:

Je ne pensais pas que vous auriez des difficultés à lire le code court, alors lisez l'aidehttps://www.mql5.com/ru/docs/trading/ordercalcmargin.

Merci, j'ai déjà trouvé la solution)

Je viens de commencer à apprendre MQL5. J'ai dû poser ma question au mauvais endroit.

 
Différence entre les plates-formes 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:
Différence multiplateforme ArrayCopy.

Évidemment, pour que cela ne fasse aucune différence, il faut écrire

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

soit

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

ou tous les défauts dans ce contexte

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

Évidemment, pour que cela ne fasse aucune différence, il faut écrire

soit

ou tous les défauts dans ce contexte

Voilà le problème.

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

Si la fonction renvoie zéro, alors MQL4 et MQL5 auront des résultats différents.

 
fxsaber:

Voici le problème.

Si la fonction renvoie zéro, MQL4 et MQL5 auront des résultats différents.

Ainsi, GetAmountToCopy() résout ce problème au cas où la fonction renvoie zéro.

Par exemple :

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

Voici le problème.

Si la fonction renvoie zéro, MQL4 et MQL5 auront des résultats différents.

Ce que vous calculez là n'est pas très clair. Il peut y avoir plusieurs variantes de retour de GetAmountToCopy().

Si 0 est pour ne rien copier (c'est la condition qui cause le problème selon moi) et -1 est pour copier le tableau entier, vous devriez évidemment spécifier des valeurs de retour autres que 0 et -1 au cas où vous voudriez ne rien copier. Par exemple, renvoyer EMPTY_VALUE. Dans ce cas, nous devrions probablement surcharger la fonction ArrayCopy() qui vérifiera d'abord ce qui lui est transmis par GetAmountToCopy(). S'il s'agit de EMPTY_VALUE, quittez la fonction. Pour le reste, si la constante WHOLE_ARRAY est utilisée, la taille des données à copier dans MQL5 et MQL4 sera sélectionnée correctement.

 
Artyom Trishkin:

Ce n'est pas très clair ce que vous calculez là.

Je ne comprends pas très bien pourquoi vous écrivez sur les implémentations possibles des différences entre MQL4/5. Je viens de noter ces différences pour ceux qui écrivent du code multiplateforme.

Les différences se sont déjà accumulées pour un article. Quelqu'un devrait l'écrire.

 
fxsaber:

Je ne sais pas vraiment pourquoi vous écrivez sur les solutions de contournement possibles des différences entre MQL4 et MQL5. Je viens de noter ces différences pour ceux qui écrivent du code multiplateforme.

Les différences se sont déjà accumulées pour un article. Quelqu'un devrait l'écrire.

Je croyais que c'était une question. Bien. Je peux supprimer mes messages.

 

Seulement soupçonné avant, maintenant confirmé. Il est facile d'avoir des fuites de mémoire lorsqu'on travaille avec des ressources.


Exemple.

#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 via SB imprime un graphique d'un tableau numérique sur un graphique. Vous pouvez alors supprimer manuellement ce graphique (objet), mais la ressource affectée à ce graphique restera à jamais suspendue en mémoire en mode lecture seule. Il ne peut pas être supprimé, car seul le script propriétaire peut le faire (voir la ligne en surbrillance).


Il n'y a pas de fonctionnalité dans MQL pour libérer la mémoire ainsi occupée. Soyez particulièrement prudent avec cela sur les VPS.

 
fxsaber:

Seulement soupçonné avant, maintenant confirmé. Il est facile d'avoir des fuites de mémoire lorsqu'on travaille avec des ressources.


Exemple.


Un script via SB imprime un graphique d'un tableau numérique sur un graphique. Vous pouvez alors supprimer manuellement ce graphique (objet), mais la ressource affectée à ce graphique restera à jamais suspendue en mémoire en mode lecture seule. Il ne peut pas être supprimé, car seul le script propriétaire peut le faire (voir la ligne en surbrillance).


Il n'y a pas de fonctionnalité dans MQL pour libérer la mémoire ainsi occupée. Soyez particulièrement prudent sur les VPS.

Lorsque vous recevez un message concernant une fuite de mémoire, cela signifie qu'il n'y a pas eu de commande explicite pour libérer cette mémoire.

Lorsqu'un programme se termine (c'est à ce moment-là que vous recevez ces messages), il libère en tout état de cause toute la mémoire, y compris la mémoire fuyante.