CArrayObj AddArray(..) Issue - Parameter conversion not allowed ??

 

Hello everyone,

I hope you're all doing very good...

I found an issue while trying to create an array of MyPoint objects and then add it to the Vector Object but all my attempts and researches failed...

This small code gives an error of "Parameter conversion not allowed" and "Invalid Access Array". I am not sure what's wrong with it, can some please point to the issue and how to fix it ?


   MyPoint *pArray[5];
   
   for(int i = 0; i < 5; i++){
      pArray[i] = new MyPoint(-i, -i*12);
   }

   Vector.AddArray(pArray);


The full code below works fine without the code above. I can use the add function of CArrayObj class to add individual MyPoint objects, but when I try to add an Array of MyPoint objects to the Vector Objects using the AddArray function, the code fails! 


How to add an Array of MyPoints to the Vector Object ?


#property strict

#include <Arrays/ArrayObj.mqh>

template<typename T>
class CVector : public CArrayObj{
   public:
      T  *operator[](const int index) const { return (T*)At(index);}
};


class MyPoint : public CObject{

   public:
      MyPoint(){}
      MyPoint(int x, int y):m_X(x),m_Y(y){}
      double m_X;
      double m_Y;
};


void Main(){

   CVector <MyPoint> Vector;

   for(int i = 0; i < 5; i++){
      int rand1 = MathRand()%20 + 1;
      int rand2 = MathRand()%20 + 1;
      
      Vector.Add(new MyPoint(rand1, rand1*10));
   }

   //************************************
   MyPoint *pArray[5];
   
   for(int i = 0; i < 5; i++){
      pArray[i] = new MyPoint(-i, -i*12);
   }
   
  
   Vector.AddArray(pArray);

   //************************************

   string text = "";
   
   for(int i = 0; i < Vector.Total(); i++){
   
      text += "(" + (string)Vector[i].m_X + ", " +  (string)Vector[i].m_Y + ")   ";
      
   }
   
   Comment(text);
   
   
   
}


int OnInit()
  {

   Main();
   
   return(INIT_SUCCEEDED);
  }


void OnTick()
  {

   
  }

 
   CVector <MyPoint *> Vector;

Try this.

 
lippmaje #:

Try this.

Thank you lippmaje,

I tried it but it didn't work...


I fixed the issue. The AddArray function of CArrayObj doesn't accept MyPoint array as a parameter. It accepts another CVector object instead.


Thank you

 

You could extend your class like so:

template<typename T>
class CVector : public CArrayObj
  {
public:
                     CVector() {}
                     CVector(T &arr[])
     {
      int num=ArraySize(arr);
      if(!Reserve(num))
         return;
      //--- add
      for(int i=0; i<num; i++)
         m_data[m_data_total++]=arr[i];
      m_sort_mode=-1;
     }
   T                 operator[](const int index) const { return (T)At(index);}
  };

Note the array constructor here. You're now able to intialize a temporary vector with your array and add this to your main vector:

void Main()
  {
   CVector <MyPoint *> Vector;

   for(int i = 0; i < 5; i++)
     {
      int rand1 = MathRand()%20 + 1;
      int rand2 = MathRand()%20 + 1;
      Vector.Add(new MyPoint(rand1, rand1*10));
     }

   MyPoint *pArray[5];

   for(int i = 0; i < 5; i++)
     {
      pArray[i] = new MyPoint(-i, -i*12);
     }

   CVector <MyPoint *> array(pArray);
   Vector.AddArray(&array);
Maybe a bit clumsy but should work. Also, think about what should happen to the allocated objects. There must be a delete somewhere later to avoid memory leaks. 
 
lippmaje #:

You could extend your class like so:

Note the array constructor here. You're now able to intialize a temporary vector with your array and add this to your main vector:

Maybe a bit clumsy but should work. Also, think about what should happen to the allocated objects. There must be a delete somewhere later to avoid memory leaks. 


Thank you very much lippmaje, your code works very well.

There are no memory leaks when I recompile your code multiple times. Is it necessary to use "delete" to avoid memory leaks when MT4 doesn't show any memory leaks !


This code also works with no memory leaks:


#property strict

#include <Arrays/ArrayObj.mqh>

template<typename T>
class CVector : public CArrayObj{
   public:
      T  *operator[](const int index) const { return (T*)At(index);}
};


class MyPoint : public CObject{

   public:
      MyPoint(){}
      MyPoint(int x, int y):m_X(x),m_Y(y){}
      double m_X;
      double m_Y;
};


void Main(){

   CVector <MyPoint> Vector;

   for(int i = 0; i < 5; i++){
      int rand1 = MathRand()%20 + 1;
      int rand2 = MathRand()%20 + 1;
      
      Vector.Add(new MyPoint(rand1, rand1*10));
   }


   CVector <MyPoint> pArray;
   
   
   for(int i = 0; i < 5; i++){
      pArray.Add(new MyPoint(-i, -i*12));
   }
   
  
   Vector.AddArray(&pArray);


//*********************************************************************************
   string text = "";
   
   for(int i = 0; i < Vector.Total(); i++){
   
      text += "(" + (string)Vector[i].m_X + ", " +  (string)Vector[i].m_Y + ")   ";
      
   }
   
   Comment(text);
//*********************************************************************************
   
   
}


int OnInit()
  {

   Main();
   
   return(INIT_SUCCEEDED);
  }


void OnTick()
  {

   
  }
 

That's because CArrayObj cares about deletion of its values. Bad class design. You're running into problems if you work with elements contained in more than one array.

You can shut this behavior off by calling FreeMode(false). Otherwise, if you're ok with this, let it on.

Reason: