Best way to handle array/list of object MQL5. Critical error while running expert. Array out of range.

 

I've designed a library system I'm trying to implement in MT5, I'm having difficulty managing lists of objects. What would be the best approach to making a list of objects?

//+------------------------------------------------------------------+
//|                                                        Layer.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Brain\Neuron.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class Layer
  {
private:

public:
   Neuron            neurons[];

                     Layer();
                    ~Layer();

   void              SetDoubles(double &inputDoubles[]);
   void              SetNeurons(Neuron &inputNeurons[]);
   void              SetLayer(Layer &inputLayer);
   void              OutputLayer(Layer &inputLayer, double &thresholds[]);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Layer::Layer()
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Layer::~Layer()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Layer::SetNeurons(Neuron &inputNeurons[])
  {
   for(int i = 0; i < ArraySize(inputNeurons); i++)
     {
      this.neurons[i] = inputNeurons[i];
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Layer::SetDoubles(double &inputDoubles[])
  {
   Neuron _neurons[];
   for(int i = 0; i < ArraySize(inputDoubles); i++)
     {
      _neurons[i] = new Neuron;
      _neurons[i].SetInputValue(inputDoubles[i]);
     }

   this.SetNeurons(neurons);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Layer::SetLayer(Layer &inputLayer)
  {
   Neuron _neurons[];
   for(int i = 0; i < ArraySize(inputLayer.neurons); i++)
     {
      _neurons[i] = new Neuron; // <--------------------------------------------------------------- Line 60 ################################### Critical error while running expert. Array out of range.
      _neurons[i].SetInputNeurons(inputLayer.neurons);
     }

   this.SetNeurons(_neurons);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Layer::OutputLayer(Layer &inputLayer, double &thresholds[])
  {
   Neuron _neurons[];
   for(int i = 0; i < ArraySize(thresholds); i++)
     {
      _neurons[i] = new Neuron;
      _neurons[i].SetInputValue(thresholds[i]);
      _neurons[i].SetInputNeurons(inputLayer.neurons);
     }

   this.SetNeurons(_neurons);
  }
//+------------------------------------------------------------------+


I've tried things like this:

void Layer::SetNeurons(Neuron &inputNeurons[])
  {
   this.neurons = inputNeurons;
  }

This for some reason is also not allowed.

 

Your critical error is because you didn't dimension _neurons[]. That would be true whether it was an array of objects or any other type. Adding the line:

ArrayResize(_neurons, ArraySize(_neurons) + 1);

before the offending line, inside the loop, would fix it.

As for your title question, I have used this with good results.

https://www.mql5.com/en/docs/standardlibrary/datastructures/carrayobj

 
Anthony Garot:

Your critical error is because you didn't dimension _neurons[]. That would be true whether it was an array of objects or any other type. Adding the line:

before the offending line, inside the loop, would fix it.

As for your title question, I have used this with good results.

https://www.mql5.com/en/docs/standardlibrary/datastructures/carrayobj

Don't do it this way, if there are a lot of neurons, it will be slow.

As the size is known before the loop you can just do :

ArrayResize(_neurons, ArraySize(thresholds));

Or alternatively, inside the loop :

ArrayResize(_neurons, ArraySize(_neurons) + 1, ArraySize(thresholds));
I would also suggest to use a size variable instead of calling ArraySize() on each iteration of the loop.
 
Anthony Garot:

Your critical error is because you didn't dimension _neurons[]. That would be true whether it was an array of objects or any other type. Adding the line:

before the offending line, inside the loop, would fix it.

As for your title question, I have used this with good results.

https://www.mql5.com/en/docs/standardlibrary/datastructures/carrayobj

Thanks that worked like a charm!
 
Alain Verleyen:

Don't do it this way, if there are a lot of neurons, it will be slow.

As the size is known before the loop you can just do :

Or alternatively, inside the loop :

I would also suggest to use a size variable instead of calling ArraySize() on each iteration of the loop.
Thanks! Is this a better approach than using a CList?
 
Alain Verleyen:

Don't do it this way, if there are a lot of neurons, it will be slow.

Indeed. I should have spelled this out more fully like I did in this post:

https://www.mql5.com/en/forum/332320#comment_14900743

 
Anthony Garot:

Indeed. I should have spelled this out more fully like I did in this post:

https://www.mql5.com/en/forum/332320#comment_14900743

I knew you knew but now I had the others let know.

By the way you can also use the Pocket tools, it's nicer and quicker.

 
chemmens:
Thanks! Is this a better approach than using a CList?

It is better than CList but not better than CArrayObj. The latter wraps a C-style array and for all intensive purposes is equally as performant. Your code will also be much more elegant and readable, and it will also save you a lot of developer time. 

Reason: