ArrayFree

Esta función deja libre el búfer de cualquier array dinámico y pone el tamaño de la dimensión cero a 0.

void  ArrayFree(
   void&  array[]      // array
   );

Parámetros

array[]

[in]  Array dinámico.

Valor devuelto

No hay valor devuelto.

Nota

La necesidad de utilizar la función ArrayFree() durante la escritura de los scripts e indicadores puede surgir con poca frecuencia. Es que cuando el trabajo del script se finaliza la memoria utilizada se libera en seguida, el trabajo principal con los arrays en los indicadores personalizados consiste en el acceso a los búferes de indicadores cuyos tamaños se controlan automáticamente por el subsistema ejecutivo del terminal.

Si en el programa es necesario administrar la memoria manualmente en unas condiciones dinámicas complicadas, la función ArrayFree()permite al usuario liberar la memoria ocupada por un array dinámico ya innecesario de forma explícita e inmediata.

Ejemplo:

#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Label.mqh>
#include <Controls\ComboBox.mqh>
//--- constantes predefinidas
#define X_START 0
#define Y_START 0
#define X_SIZE 280
#define Y_SIZE 300
//+------------------------------------------------------------------+
//| Clase de diálogo para trabajar con la memoria                    |
//+------------------------------------------------------------------+
class CMemoryControl : public CAppDialog
  {
private:
   //--- tamaño del array
   int               m_arr_size;
   //--- arrays
   char              m_arr_char[];
   int               m_arr_int[];
   float             m_arr_float[];
   double            m_arr_double[];
   long              m_arr_long[];
   //--- etiquetas
   CLabel            m_lbl_memory_physical;
   CLabel            m_lbl_memory_total;
   CLabel            m_lbl_memory_available;
   CLabel            m_lbl_memory_used;
   CLabel            m_lbl_array_size;
   CLabel            m_lbl_array_type;
   CLabel            m_lbl_error;
   CLabel            m_lbl_change_type;
   CLabel            m_lbl_add_size;
   //--- botones
   CButton           m_button_add;
   CButton           m_button_free;
   //--- cajas combinadas
   CComboBox         m_combo_box_step;
   CComboBox         m_combo_box_type;
   //--- valor actual del tipo del array de la caja combinada
   int               m_combo_box_type_value;
 
public:
                     CMemoryControl(void);
                    ~CMemoryControl(void);
   //--- método de creación del objeto de la clase
   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
   //--- manejador de eventos del gráfico
   virtual bool      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
 
protected:
   //--- crear etiqueta
   bool              CreateLabel(CLabel &lbl,const string name,const int x,const int y,const string str,const int font_size,const int clr);
   //--- crear elementos de control
   bool              CreateButton(CButton &button,const string name,const int x,const int y,const string str,const int font_size,const int clr);
   bool              CreateComboBoxStep(void);
   bool              CreateComboBoxType(void);
   //--- manejadores de eventos
   void              OnClickButtonAdd(void);
   void              OnClickButtonFree(void);
   void              OnChangeComboBoxType(void);
   //--- métodos de trabajo con array actual
   void              CurrentArrayFree(void);
   bool              CurrentArrayAdd(void);
  };
//+------------------------------------------------------------------+
//| Liberación de memoria del array actual                           |
//+------------------------------------------------------------------+
void CMemoryControl::CurrentArrayFree(void)
  {
//--- reiniciar el tamaño del array
   m_arr_size=0;
//--- liberación del array
   if(m_combo_box_type_value==0)
      ArrayFree(m_arr_char);
   if(m_combo_box_type_value==1)
      ArrayFree(m_arr_int);
   if(m_combo_box_type_value==2)
      ArrayFree(m_arr_float);
   if(m_combo_box_type_value==3)
      ArrayFree(m_arr_double);
   if(m_combo_box_type_value==4)
      ArrayFree(m_arr_long);
  }  
//+------------------------------------------------------------------+
//| Intento de agregar memoria para array actual                     |
//+------------------------------------------------------------------+
bool CMemoryControl::CurrentArrayAdd(void)
  {
//--- salir si el tamaño de la memoria utilizada supera el tamaño de la memoria física
   if(TerminalInfoInteger(TERMINAL_MEMORY_PHYSICAL)/TerminalInfoInteger(TERMINAL_MEMORY_USED)<2)
      return(false);
//--- intento de adjudicación de la memoria de acuerdo con el tipo actual
   if(m_combo_box_type_value==0 && ArrayResize(m_arr_char,m_arr_size)==-1)
      return(false);
   if(m_combo_box_type_value==1 && ArrayResize(m_arr_int,m_arr_size)==-1)
      return(false);
   if(m_combo_box_type_value==2 && ArrayResize(m_arr_float,m_arr_size)==-1)
      return(false);
   if(m_combo_box_type_value==3 && ArrayResize(m_arr_double,m_arr_size)==-1)
      return(false);
   if(m_combo_box_type_value==4 && ArrayResize(m_arr_long,m_arr_size)==-1)
      return(false);
//--- memoria adjudicada
   return(true);
  }  
//+------------------------------------------------------------------+
//| Manejo de eventos                                                |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CMemoryControl)
ON_EVENT(ON_CLICK,m_button_add,OnClickButtonAdd)
ON_EVENT(ON_CLICK,m_button_free,OnClickButtonFree)
ON_EVENT(ON_CHANGE,m_combo_box_type,OnChangeComboBoxType)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CMemoryControl::CMemoryControl(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CMemoryControl::~CMemoryControl(void)
  {
  }
//+------------------------------------------------------------------+
//| Método de creación del objeto de la clase                        |
//+------------------------------------------------------------------+
bool CMemoryControl::Create(const long chart,const string name,const int subwin,
                            const int x1,const int y1,const int x2,const int y2)
  {
//--- creación del objeto de la clase basa
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//--- preparación de las cadenas para las etiquetas
   string str_physical="Memory physical = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_PHYSICAL)+" Mb";
   string str_total="Memory total = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_TOTAL)+" Mb";
   string str_available="Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE)+" Mb";
   string str_used="Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" Mb";
//--- crear etiquetas
   if(!CreateLabel(m_lbl_memory_physical,"physical_label",X_START+10,Y_START+5,str_physical,12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_memory_total,"total_label",X_START+10,Y_START+30,str_total,12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_memory_available,"available_label",X_START+10,Y_START+55,str_available,12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_memory_used,"used_label",X_START+10,Y_START+80,str_used,12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_array_type,"type_label",X_START+10,Y_START+105,"Array type = double",12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_array_size,"size_label",X_START+10,Y_START+130,"Array size = 0",12,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_error,"error_label",X_START+10,Y_START+155,"",12,clrRed))
      return(false);
   if(!CreateLabel(m_lbl_change_type,"change_type_label",X_START+10,Y_START+185,"Change type",10,clrBlack))
      return(false);
   if(!CreateLabel(m_lbl_add_size,"add_size_label",X_START+10,Y_START+210,"Add to array",10,clrBlack))
      return(false);
//--- crear elementos de control
   if(!CreateButton(m_button_add,"add_button",X_START+15,Y_START+245,"Add",12,clrBlue))
      return(false);
   if(!CreateButton(m_button_free,"free_button",X_START+75,Y_START+245,"Free",12,clrBlue))
      return(false);
   if(!CreateComboBoxType())
      return(false);
   if(!CreateComboBoxStep())
      return(false);
//--- inicialización de variable
   m_arr_size=0;
//--- ejecución con éxito
   return(true);
  }
//+------------------------------------------------------------------+
//| Crear el botón                                                   |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateButton(CButton &button,const string name,const int x,
                                  const int y,const string str,const int font_size,
                                  const int clr)
  {
//--- crear el botón
   if(!button.Create(m_chart_id,name,m_subwin,x,y,x+50,y+20))
      return(false);
//--- texto
   if(!button.Text(str))
      return(false);
//--- tamaño de la fuente
   if(!button.FontSize(font_size))
      return(false);
//--- color de la etiqueta
   if(!button.Color(clr))
      return(false);
//--- agregamos el botón a los elementos de control
   if(!Add(button))
      return(false);
//--- ejecución con éxito
   return(true);
  }
//+------------------------------------------------------------------+
//| Crear la caja combinada para el tamaño del array                              |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateComboBoxStep(void)
  {
//--- crear la caja combinada
   if(!m_combo_box_step.Create(m_chart_id,"step_combobox",m_subwin,X_START+100,Y_START+185,X_START+200,Y_START+205))
      return(false);
//--- agregar elementos a la caja combinada
   if(!m_combo_box_step.ItemAdd("100 000",100000))
      return(false);
   if(!m_combo_box_step.ItemAdd("1 000 000",1000000))
      return(false);
   if(!m_combo_box_step.ItemAdd("10 000 000",10000000))
      return(false);
   if(!m_combo_box_step.ItemAdd("100 000 000",100000000))
      return(false);
//--- establecer el elemento actual de la caja combinada
   if(!m_combo_box_step.SelectByValue(1000000))
      return(false);
//--- agregamos la caja combinada a los elementos de control
   if(!Add(m_combo_box_step))
      return(false);
//--- ejecución con éxito
   return(true);
  }
//+------------------------------------------------------------------+
//| Crear la caja combinada para el tipo del array                   |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateComboBoxType(void)
  {
//--- crear la caja combinada
   if(!m_combo_box_type.Create(m_chart_id,"type_combobox",m_subwin,X_START+100,Y_START+210,X_START+200,Y_START+230))
      return(false);
//--- agregar elementos a la caja combinada
   if(!m_combo_box_type.ItemAdd("char",0))
      return(false);
   if(!m_combo_box_type.ItemAdd("int",1))
      return(false);
   if(!m_combo_box_type.ItemAdd("float",2))
      return(false);
   if(!m_combo_box_type.ItemAdd("double",3))
      return(false);
   if(!m_combo_box_type.ItemAdd("long",4))
      return(false);
//--- establecer el elemento actual de la caja combinada
   if(!m_combo_box_type.SelectByValue(3))
      return(false);
//--- memorizamos el elemento actual de la caja combinada
   m_combo_box_type_value=3;
//--- agregamos la caja combinada a los elementos de control
   if(!Add(m_combo_box_type))
      return(false);
//--- ejecución con éxito
   return(true);
  }
//+------------------------------------------------------------------+
//| Crear etiqueta                                                   |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateLabel(CLabel &lbl,const string name,const int x,
                                 const int y,const string str,const int font_size,
                                 const int clr)
  {
//--- crear etiqueta
   if(!lbl.Create(m_chart_id,name,m_subwin,x,y,0,0))
      return(false);
//--- texto
   if(!lbl.Text(str))
      return(false);
//--- tamaño de la fuente
   if(!lbl.FontSize(font_size))
      return(false);
//--- color
   if(!lbl.Color(clr))
      return(false);
//--- agregamos etiqueta a los elementos de control
   if(!Add(lbl))
      return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Manejador del evento de pulsación del botón "Add"                |
//+------------------------------------------------------------------+
void CMemoryControl::OnClickButtonAdd(void)
  {
//--- aumentamos el tamaño del array
   m_arr_size+=(int)m_combo_box_step.Value();
//--- intentamos adjudicar la memoria para el array actual
   if(CurrentArrayAdd())
     {
      //--- memoria adjudicada, mostramos el estado actual sobre la pantalla 
      m_lbl_memory_available.Text("Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE)+" Mb");
      m_lbl_memory_used.Text("Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" Mb");
      m_lbl_array_size.Text("Array size = "+IntegerToString(m_arr_size));
      m_lbl_error.Text("");
     }
   else
     {
      //--- no se ha podido adjudicar la memoria, mostramos mensaje sobre el error
      m_lbl_error.Text("Array is too large, error!");
      //--- devolvemos el tamaño anterior del array
      m_arr_size-=(int)m_combo_box_step.Value();
     }
  }
//+------------------------------------------------------------------+
//| Manejador del evento de pulsación del botón "Free"               |
//+------------------------------------------------------------------+
void CMemoryControl::OnClickButtonFree(void)
  {
//--- liberamos la memoria del array actual
   CurrentArrayFree();
//--- mostramos el estado actual sobre la pantalla
   m_lbl_memory_available.Text("Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE)+" Mb");
   m_lbl_memory_used.Text("Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" Mb");
   m_lbl_array_size.Text("Array size = 0");
   m_lbl_error.Text("");
  }
//+------------------------------------------------------------------+
//| Manejador del evento de la modificación de caja combinada        |
//+------------------------------------------------------------------+
void CMemoryControl::OnChangeComboBoxType(void)
  {
//--- prueba, si se ha cambiado el tipo del array
   if(m_combo_box_type.Value()!=m_combo_box_type_value)
     {
      //--- liberamos la memoria del array actual
      OnClickButtonFree();
      //--- trabajamos con otro tipo del array
      m_combo_box_type_value=(int)m_combo_box_type.Value();
      //--- mostramos nuevo tipo del array en la pantalla
      if(m_combo_box_type_value==0)
         m_lbl_array_type.Text("Array type = char");
      if(m_combo_box_type_value==1)
         m_lbl_array_type.Text("Array type = int");
      if(m_combo_box_type_value==2)
         m_lbl_array_type.Text("Array type = float");
      if(m_combo_box_type_value==3)
         m_lbl_array_type.Text("Array type = double");
      if(m_combo_box_type_value==4)
         m_lbl_array_type.Text("Array type = long");
     }
  }
//--- objeto de la clase CMemoryControl
CMemoryControl ExtDialog;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- crear diálogo
   if(!ExtDialog.Create(0,"MemoryControl",0,X_START,Y_START,X_SIZE,Y_SIZE))
      return(INIT_FAILED);
//--- iniciar
   ExtDialog.Run();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   ExtDialog.Destroy(reason);
  }
//+------------------------------------------------------------------+
//| Expert chart event function                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }