How to avoid array out of range

15,802

Solution 1

While the arrays (problem) look similar, there is a major difference

MQL4 Indicators use "other" mechanics for handling arrays than "ordinary" arrays have.

...  Testing pass stopped due to a critical error in the EA
...  array out of range in '!2015-09-08___!EA 2xAMA 01 2015-09-08_msMOD_0.00.mq4' (519,39)

Yes, MT4 throws Fatal Error on an attempt to handle a wrong ptr->array[aStaticSIZE] and one has to take due care to either avoid such case, or trim ptr ( alike in low-latency circular-buffer scenarios ) not to direct past the array boundary ( underflow / overflow ) or extend the array[] via ArrayResize() so as to keep pace with the ptr growth ( until memory allows ) ) on arrays declared as dynamic double Array[];, however MQL4 Technical Indicators have completely other situation.


Limits? Yes. . . . . . ( And one ought to review on each New-MQL4.56789 stealth update )

As of a "New"-MQL4.56789-Build-840, your "ordinary" array cannot have more than 2.147.483.647 elements, if O/S memory-pool manager allows, so you ought to have plenty of space, even if using higher dimensionality mappings { 2D | 3D | 4D }.

Years ago 've used many parallel 2D / 3D-arrays for fast and private ( safely encapsulated ) heap / stack-handlers for maintaining highly dynamic entities in scales of 100k+ rows / 2D-planes and all worked well-oiled in old-MQL4.

So some 7k+ elements should not make you any worries.


Indicators use array indirectly, via an automated Buffer-handler

In this sense, your code need not care about these issues.

/*
#property "pragmas" help MQL4-compiler decide about setup of internal handlers
          so this part of code "speaks" to MetaLang.exe at compile-time*/

#property indicator_buffers      3             // .DEF N-Buffs

#property indicator_color1       White         // .SET Buf[0].color
#property indicator_color2       SeaGreen      // .SET Buf[1].color
#property indicator_color3       FireBrick     // .SET Buf[2].color

#property indicator_width1       1             // .SET Buf[0].width
#property indicator_width2       2             // .SET Buf[1].width
#property indicator_width3       2             // .SET Buf[2].width

         double   buffer_line_up[],            // .DEF Arrays as dynamic ...[]
                  buffer_line_dn[],            //      with human-readable-names
                  buffer_line_ax[];            //      and MT4 will take care

int   init()   {

      SetIndexBuffer(   0, buffer_line_ax );   // .ASSOC IndexBuffer.0<-array[]
      SetIndexLabel(    0, "SuperTrend"     );

      SetIndexBuffer(   1, buffer_line_up   ); // .ASSOC IndexBuffer.0<-array[]
      SetIndexLabel(    1, "Up Trend"       );
      SetIndexStyle(    1, DRAW_LINE,
                           STYLE_SOLID,
                           1 + int( ATR_Multiplier / 5 ),
                           SeaGreen
                           );

      SetIndexBuffer(   2, buffer_line_dn );   // .ASSOC IndexBuffer.0<-array[]
      SetIndexLabel(    2, "Down Trend"     );
      SetIndexStyle(    2, DRAW_LINE,
                           STYLE_SOLID,
                           1 + int( ATR_Multiplier / 5 ),
                           FireBrick
                           );

      SetIndexDrawBegin(0, ATR_Period );       // .DEF initial depth of Buffer before 1st GUI output

      IndicatorShortName( "xxxx[" + ATR_Period + "," + ATR_Multiplier + "]" );

      IndicatorDigits( MarketInfo( Symbol(), MODE_DIGITS ) );

Solution 2

I had a similar issue, that I always got "Array out of range" errors for one of my buffers. I checked with ArraySize(), which returned 0.

In the end I just forgot to call SetIndexBuffer(...) for this buffer array in onInit() {...} of my indicator.

Since I was using an internal buffer without drawing lines, I used the IndicatorBuffers() function to increase the amount of buffers first and then registered my additonal buffer using SetIndexBuffer(...).

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   IndicatorBuffers(5);

//buffers with #properties settings
   SetIndexBuffer(0,Buffer1);
   SetIndexBuffer(1,Buffer2);
   SetIndexBuffer(2,Buffer3);
   SetIndexBuffer(3,Buffer4);

//additional buffer without #properties 
   SetIndexBuffer(4,AdditionalBuffer);
Share:
15,802
JLLMNCHR
Author by

JLLMNCHR

Updated on June 04, 2022

Comments

  • JLLMNCHR
    JLLMNCHR about 2 years

    Does somebody know how to avoid the error array out of range when trying to display long number of bars (lets say 7000) in an indicator buffer?