Features of the mql5 language, subtleties and tricks - page 167

 
Igor Makanu:

didn't think you would have any trouble reading the short code, then read the helphttps://www.mql5.com/ru/docs/trading/ordercalcmargin

Thanks, already figured it out )

I just started to learn MQL5. I must have put my question in a wrong place

 
Cross-platform difference 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:
Cross-platform difference ArrayCopy.

Obviously, in order to make no difference, you have to write

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

either

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

or all default in this context

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

Obviously, in order to make no difference, you have to write

either

or all default in this context

Here's the problem.

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

If the function returns zero, then MQL4 and MQL5 will have different results.

 
fxsaber:

Here is the problem.

If the function returns zero, MQL4 and MQL5 will have different results.

So, GetAmountToCopy() solves this problem in case the function should return zero.

For example:

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

Here is the problem.

If the function returns zero, MQL4 and MQL5 will have different results.

It is not quite clear what you are calculating there. There can be several variants of return from GetAmountToCopy().

If 0 is to copy nothing (this is the condition which causes the problem, as I understand it) and -1 is to copy the entire array, you should obviously specify return values other than 0 and -1 in case you want to copy nothing. For example, return EMPTY_VALUE. In this case we should probably overload the ArrayCopy() function which will first check what is passed to it from GetAmountToCopy(). If it is EMPTY_VALUE, then exit the function. For the rest, if the WHOLE_ARRAY constant is used, the size of data to be copied in both MQL5 and MQL4 will be selected correctly.

 
Artyom Trishkin:

It's not very clear what you're calculating there.

It's not quite clear to me why you're writing about possible implementations of MQL4/5 differences. I just noted these differences for those who write cross-platform code.

The differences have already accumulated for an article. Someone should write it.

 
fxsaber:

I'm not quite sure why you're writing about possible workarounds to the MQL4/5 differences. I just noted these differences for those who write cross-platform code.

The differences have already accumulated for an article. Someone should write it.

I thought it was a question. Good. I can delete my messages.

 

Only suspected before, now confirmed. It's easy to get memory leaks when working with resources.


Example.

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


A script via SB prints a graph of a numeric array to a chart. You can then manually delete this chart (object), but the resource assigned to this chart will remain forever hanging in memory in read-only mode. It cannot be deleted, because only the owner script can delete it (see the highlighted line).


There is no functionality in MQL to free up so occupied memory. Be especially careful with this on VPS.

 
fxsaber:

Only suspected before, now confirmed. It's easy to get memory leaks when working with resources.


Example.


A script via SB prints a graph of a numeric array to a chart. You can then manually delete this chart (object), but the resource assigned to this chart will remain forever hanging in memory in read-only mode. It cannot be deleted, because only the owner script can delete it (see the highlighted line).


There is no functionality in MQL to free up so occupied memory. Be especially careful on VPS.

When you get a message about a memory leak, it means that there was no explicit command to free that memory.

When a program terminates (which is when you get these messages), it frees up all memory, including the leaked memory, in any case.

Reason: