Leaked memory, objects left

 

Hi all

Apologies for the long post but here is my problem:

I'm writing an indicator to continuously (ie on every OnCalculate call), plot the last few fractals, and draw support and resistance lines on those closest to High[0] and Low[0].The high fractals are those higher than High[0], and the low ones lower than Low[0]. 

I actually have 2 issues:

1.the leaked memory thing...runtime error that says there are x amount of CPivot objects still left.

2. the fact that the list doesn't get sorted and hence  the lines getting drawn on the wrong pivot.

If someone can please please help me and point the errors out. 

I use objects of custom class CPivot for the fractals that gets added to a CList.

class CPivot : public CObject
{
public: 
   double m_price;
   datetime m_datetime;
   PIVOT_TYPE m_pivottype;
   CPivot() {m_price=0.0; m_datetime=0; m_pivottype=PT_UNDEF;}
   ~CPivot() {}
   virtual int Compare(const CObject* node, const int mode=0); 
};

The function to look for the fractals:

int GetTypicalFracPivot(int b,CPivot& p) 
{
   if (b<2) return PT_UNDEF; //can't determine fractal if on bar 1 or 0
   if (Low[b+2] >= Low[b] && Low[b+1] >= Low[b] && Low[b-2] >= Low[b] && Low[b-1] >= Low[b])
    {p.m_datetime = Time[b];
     p.m_price = Low[b];
     p.m_pivottype = PT_TYPICALFRACLOW;
     return PT_TYPICALFRACLOW;}
   if (High[b+2] <= High[b] && High[b+1] <= High[b] && High[b-2] <= High[b] && High[b-1] <= High[b])
    {p.m_datetime = Time[b];
     p.m_price = High[b];
     p.m_pivottype = PT_TYPICALFRACHIGH; 
     return  PT_TYPICALFRACHIGH;}
   return PT_UNDEF;
}

Init and deinit code:

CList*         HighPivotList;
CList*         LowPivotList;

input int Lookback_period = 50;

int OnInit()
  {
   //rest of code here...
   HighPivotList = new CList;
   HighPivotList.FreeMode(true);
   LowPivotList = new CList;
   LowPivotList.FreeMode(true);
   
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
{ 
   delete HighPivotList;
   delete LowPivotList;
   for (int i=0;i<4;i++)
    DeleteLine(SRLines[i]); //Deleteline is not shown here

I will try to explain the code in green  comments for OnCalculate:

       HighPivotList.Clear(); //clear contents of list
       LowPivotList.Clear(); 
       ClearChart();	//This deletes all drawn lines and clears the onscreen buffers...see below
       for (int i=2;i<Lookback_period;i++) 
       {
         p = new CPivot();
         if ( GetTypicalFracPivot(i,p)==PT_TYPICALFRACHIGH)
          { if (p.m_price >= High[0])
              HighPivotList.Add(p);
              
          }
       }
        PlotPivots(0); //Plots the high fractals, 1=for low fractals
               
        for (int i=2;i<Lookback_period;i++)
        {
         p = new CPivot();
         if (GetTypicalFracPivot(i,p)== PT_TYPICALFRACLOW)
         { if (p.m_price <= Low[0])
            LowPivotList.Add(p);
         }
       }
//rest of code here

To plot the pivots:

void PlotPivots(int k)
{  CPivot* n;

 
   if (k==0) 
   { for (int i=0;i<HighPivotList.Total();i++)
     { n = (CPivot*)(HighPivotList.GetNodeAtIndex(i));
       CloseFractalHighBuffer[iBarShift(NULL,0,n.m_datetime)] = n.m_price;
     }
   } else
   { for (int i=0;i<LowPivotList.Total();i++)
     { n = (CPivot*)(LowPivotList.GetNodeAtIndex(i));
       CloseFractalLowBuffer[iBarShift(NULL,0,n.m_datetime)] = n.m_price;
     }
   }
}

Now to draw the closest resistance line:

void DrawClosestResistance()
{ CPivot* piv;
  int k=0;
  
  HighPivotList.Sort(0); //list doesn't get sorted!
  piv = (CPivot*)(HighPivotList.GetNodeAtIndex(0)); //if last was sorted, the first object should be the one closest to High[0]
  DrawLine(SRLines[0],piv.m_datetime,piv.m_price,Time[0],piv.m_price,clrRed,STYLE_SOLID,2);
 
  WindowRedraw();
}

To clear the chart:

void ClearChart()
{
   ArrayFill(CloseFractalHighBuffer,0,ArraySize(CloseFractalHighBuffer),EMPTY_VALUE);
   ArrayFill(CloseFractalLowBuffer,0,ArraySize(CloseFractalLowBuffer),EMPTY_VALUE);
   for (int i=0;i<4;i++) DeleteLine(SRLines[i]);
   WindowRedraw();
}

Almost forgot:

The Compare method for CPivot:

int CPivot::Compare(const CObject* node,const int mode=0) 
{ CPivot* p;
   p=(CPivot*)(node);
   if (this.m_price < p.m_price) return -1;
  else if (this.m_price > p.m_price) return 1; else
    return 0;
}

Well that is about it.

I have no idea where is the memory leak, and why the list doesn't get sorted...

Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
//| Expert initialization function                                   | //| Expert deinitialization function                                 | //| Expert tick function                                             | //| test1                                                            |...
 
CobusSteyn0105: I have no idea where is the memory leak, 
         p = new CPivot();
         if ( GetTypicalFracPivot(i,p)==PT_TYPICALFRACHIGH)
          { if (p.m_price >= High[0])
              HighPivotList.Add(p);
         }

You create a pointer in p. If those two if statements are not both true, you loose the pointer. LEAK.

 
William Roeder:

You create a pointer in p. If those two if statements are not both true, you loose the pointer. LEAK.

Thank you very much William!

Do you think the fact that the list isn't sorted properly has something to do with the leak?

 
CobusSteyn0105:

Thank you very much William!

Do you think the fact that the list isn't sorted properly has something to do with the leak?

For anyone interested... the sort works perfectly in CArrayObj, but not in CList. 

Reason: