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());

この関数が0を返した場合、MQL4とMQL5では異なる結果になります。

 
fxsaber:

ここで問題です。

この関数が0を返した場合、MQL4とMQL5では異なる結果が得られます。

そこで、GetAmountToCopy()は、関数がゼロを返すべき場合にこの問題を解決する。

例えば、こんな感じです。

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

ここで問題です。

この関数が0を返した場合、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, "::"))); // Без этой строки утечка памяти.
}


SB経由のスクリプトで、数値配列のグラフをチャートに印刷する。その後、このチャート(オブジェクト)を手動で削除することができますが、このチャートに割り当てられたリソースは、読み取り専用モードでメモリ内に永遠にぶら下がったままです。オーナースクリプトのみが削除できるため、削除することはできません(ハイライトされた行を参照)。


MQLには、このように占有されたメモリーを解放する機能はありません。特にVPSの 場合は注意が必要です。

 
fxsaber:

以前は疑いしかなかったが、今は確認されている。リソースを扱うとメモリリークが発生しやすい。



SB経由のスクリプトで、数値配列のグラフをチャートに印刷する。その後、このチャート(オブジェクト)を手動で削除することができますが、このチャートに割り当てられたリソースは、読み取り専用モードでメモリ内に永遠にぶら下がったままです。オーナースクリプトのみが削除できるため、削除することはできません(ハイライトされた行を参照)。


MQLには、このように占有されたメモリーを解放する機能はありません。特にVPSでは 注意が必要です。

メモリリークに関するメッセージが表示された場合、そのメモリを解放する明示的な命令がなかったことを意味します。

プログラムが終了するとき(このようなメッセージが表示されるとき)、リークしたメモリも含めて、いずれにしてもすべてのメモリを解放する。