I'm creating a indicator that recognizes candlestick shapes.
To do that I created a separate class Candlestick
that I include to the indicator file.
The problem is that I suffer from memory leaks.
I'm new to pointers and after reading / watching a lot, I still seem to miss something here.
This is the Indicator class. The content of the Candlestick
class is irrelevant so I leave that out.
Candlestick *candles[];
void OnDeinit(const int reason)
{
for(int i = 0; i < ArraySize(candles); i++ ){
delete(candles[i]);
}
}
int OnCalculate(args here)
{
ArrayResize(candles, Bars);
for(int i = MathMax(Bars-2-IndicatorCounted(), 1); i >= 0; i--)
{
candles[i] = new Candlestick();
// Do stuff with this candle (and other candles) here e.g.
if(candles[i+1].type == BULLISH) Print("Last candle was Bullish");
}
}
When I do this I get memory leak errors. It seems that I need to delete the pointers to the candles in that dynamic array. The problem is, when and where? Because I need them in the next iteration of the for(){...}
loop. So I can't delete it there.
When I delete it in the OnDeinit()
function there are still candles out there and I still get the leak error.
How come?
You might have already realised, the MQL4
code is not C
.
Among many important differences, the key here is what does the code-execution platform ( the MetaTrader Terminal 4 ) do in what moment.
OnCalculate()
is a zombie-alike process, which gets invoked many times, but anyway, definitely not under your control.
Next, OnCalculate()
by-design does not mean a new Bar
.
MQL4
conceptually originates from days, when computing resources were many orders smaller and much more expensive in terms of their time-sharing CPU-MUX-ing during a code execution phase.
Thus the MQL4
-user-domain language retains benefits from some hidden gems, that are not accessible directly. One of these is a very efficient register-based update-processing and keeping dynamic resources allocations on minimum, for their devastatingly adverse effects on Real-Time execution predictability.
This will help you understand how to design & handle your conceptual objects way smarter, best by mimicking this "stone-age"-but-VERY-efficient behaviour ( both time-wise & memory-wise ), instead of flooding your memory-pool with infinite amount of unmanaged instances upon each call of OnCalulate()
which sprinkles an endless count of new Candlestick(); // *--> candles[]
If in doubt, just read about best practices for ArrayResize()
in the platform localhost-help/documentation, to start to realise the things that introduce overheads ( if not blocks ) in a domain, where nanoseconds
count & hurt in professional software design.