CGraphic: "incorrect casting of pointers" error (MT5 build 2265)

 

Since the update to build 2265 and after executing the following lines in my code

graph[0].CurveAdd(PnL_long,infopanel.headers_clr,CURVE_HISTOGRAM,"PnL long ("+IntegerToString(magic_id)+")");
graph[0].CalculateMaxMinValues();
graph[0].CurvePlotAll();
graph[0].Update();

I'm getting the error "incorrect casting of pointers" from the Graphic.mqh of the standard library caused by the line

CCurve *curve=m_arr_curves.At(i);

that identically appears in Graphic.mqh in both the functions CurvePlotAll() and CurveRemoveByName() (both functions cause the error);

graph[0] is an element of an object array

CGraphic graph[4];

that is a private member of the same class (=the base class) as the function that calls the above functions CurveAdd etc.

Of course, the function graph[0].Create(....) was used before trying to add any curves.

I didn't change the code and it had worked in the previous build without any issues. What's further strange: the code still compiles without error or warnings, it executes fine in the tester, but not in the debugger or with live data.

I already tried to reproduce the error with another very simple test code:

#include <Graphics/Graphic.mqh>
void OnInit() 
  {
   // generating some values for an example curve
   double sin_values[360]; double cos_values[360];
   for (int n=0;n<360;n++){sin_values[n]=sin(2*M_PI*((double)n/360));cos_values[n]=cos(2*M_PI*((double)n/360));}
   
   // draw graph
   CGraphic example;
   example.Create(0,"test",0,0,0,500,700);   
   example.CurveAdd(sin_values,clrRed,CURVE_LINES,"sin(x)");         
   example.CurveAdd(cos_values,clrRed,CURVE_LINES,"cos(x)"); 
   example.CalculateMaxMinValues();
   example.CurvePlotAll();
   example.Update();
  }

Here, I don't get any errors, so it's not like CurvePlotAll and CurveRemoveByName are completely malfunctioning with the new build, so I understand that the interaction with my own code will play its part, too, but since the error appeared since the update without any changes to the code, I guess both play their part.

It's a serious issue for me because all live EAs on my VPS are using these functions, so all my trading is down until the problem is solved.

Does anybody have an idea what might be wrong?


[edit: I suspect that it might have something to do with dynamic vs. explicit casting, but if that's the case I'm not sure what exactly I need to do to correct the problem and any help is much appreciated]

 

changing the line

CCurve *curve=m_arr_curves.At(i);

in CGraphic::CurveRemoveByName() and CGraphic::CurvePlotAll() to

CCurve *curve=dynamic_cast<CCurve*>(m_arr_curves.At(i));

seems to fix the initial problem, but then the next error already follows in the next line

if(curve.Name()==name)
        {...

leads to "invalid pointer access".


edit:

adding the condition

      if(CheckPointer(curve)!=POINTER_INVALID && curve.Name()==name)
        {...
lets the code execute without errors, but the pointer is permanently invalid
 
Chris70:

changing the line

in CGraphic::CurveRemoveByName() and CGraphic::CurvePlotAll() to

seems to fix the initial problem, but then the next error already follows in the next line

lead to "invalid pointer access".

If you have this error that means the object returned by m_arr_curves.At(i) is not a curve object, which seems weird.

graph[0].CurveAdd(PnL_long,infopanel.headers_clr,CURVE_HISTOGRAM,"PnL long ("+IntegerToString(magic_id)+")");

What type is PnL_long ?

I would also suggest you to check the return value of CurveAdd() which should be a curve but is probably not, is it NULL ?

 

PnL_long is just a dynamic 1-dimensional type double array. I'm using overload 5/8 here (--> https://www.mql5.com/en/docs/standardlibrary/graphics/cgraphic/cgraphiccurveadd).

As I said, I didn't change the code, all I did is the MT5 update. The PnL_long array is correctly sized and has meaningful values. And The CurveAdd method isn't the problem here, only CurveRemoveByName and CurvePlotAll are causing trouble.

It seems like dynamic casting has simply been forgotten here, If you have a look at the Graphic.mqh code you'll see that other methods, like CurvePlot, Redraw, CurveGetName, CurveRemoveByIndex... etc all share very similar code elements, but all  use dynamic casting.

Although I'm lacking a deeper understanding here, this doesn't seem like on purpose. But I'm no OOP expert and as you know I have no professional background in programming. so although I use OOP  this is where I currently clearly see my limits.

Documentation on MQL5: Standard Library / Scientific Charts / CGraphic / CurveAdd
Documentation on MQL5: Standard Library / Scientific Charts / CGraphic / CurveAdd
  • www.mql5.com
Standard Library / Scientific Charts / CGraphic / CurveAdd - Reference on algorithmic/automated trading language for MetaTrader 5
 
Chris70:

PnL_long is just a dynamic 1-dimensional type double array. I'm using overload 5/8 here (--> https://www.mql5.com/en/docs/standardlibrary/graphics/cgraphic/cgraphiccurveadd).

As I said, I didn't change the code, all I did is the MT5 update. The PnL_long array is correctly sized and has meaningful values. And The CurveAdd method isn't the problem here, only CurveRemoveByName and CurvePlotAll are causing trouble.

It seems like dynamic casting has simply been forgotten here, If you have a look at the Graphic.mqh code you'll see that other methods, like CurvePlot, Redraw, CurveGetName, CurveRemoveByIndex... etc all share very similar code elements, but all  use dynamic casting.

Although I'm lacking a deeper understanding here, this doesn't seem like on purpose. But I'm no OOP expert and as you know I have no professional background in programming. so although I use OOP  this is where I currently clearly see my limits.

The CurveAdd method is possibly the problem, because that's where the object is created and the pointer set. If the curve pointer assigned inside it is invalid for some reason it will lead to the later problem. That's why you should check.

As you noted the simple example your provide is working, so your problem is not a trivial one, it's certainly related to the compiler but in some special circumstances, the ones of your code. So I can't reproduce and check what the problem is, but from your code you should be able to isolate the problem.

If the pointer is valid there, that means it is corrupted later. Or it is already invalid at this point.

The dynamic_cast isn't really needed here because the m_arr_curves array is containing only Curve object.

 

I verified that the *curve pointer in CurveAdd is valid, so it must be something else.

With the above mentioned modifications (dynamic cast followed by pointer check) I can at least execute the code without crashing, but I see blank graphs without the curves if I run the code via tester or debugger (makes sense if the curve pointer in CurvePlotAll is permamently invalid). But now it gets even stranger: I copied the exact same file over to the VPS server (also running on the new MT5 build) and now ran that EA in live trading mode again: the graphs+curves were created normally and with correct axis scaling. I've got absolutely no idea what's going on... but my main concern, i.e. the broken live trading, therefore is solved. As long as my EAs continue to run live, I'm happy for now and finding out the reason now has time.

Thanks for your help and your time, Alain!

 

Like you said, Alain, it's probably compiler-related... and I now found the solution:

Before, I had the line "#include <Graphics/Graphic.mqh>" on top of the include file that contains my base class, which also is where the functions from Graphic.mqh are used.

This made sense to me, because whenever I use this base class in an EA, I want to make sure that the CGraphic class is automatically included, too. This worked without any issues with the previous build.

And as I said: also with the newest build it's not the compiler that's complaining.

Now I moved this #include command to the main EA program (that by itself doesn't use any functions from Graphic.mqh) as the first include command before any other inclusions, just to see if it makes a difference - et voilà, all problems are gone (=in this case also with the unmodified original Graphic.mqh file).

 

Puh.. I'm running into more problems with the latest build: I noticed that my neural network library (=exact same code) needs more than 20 times more training time than before (which makes it practically almost unsuable) and I can't find the reason.

I'm really fed up with this latest version and would like to skip it (=downgrade and then forbid write access to terminal64.exe) until something better comes up, which is why:

does anybody still have a copy of  terminal64.exe + metaeditor64.exe + metatester64.exe of the previous stable build (2190) and can share it here?

This would be heaven!


[mental note to future self: never update without a backup of the old version]