Errors, bugs, questions - page 2471

 
Igor Makanu:

Explain why when I create CChartObjectLabel I am not deleting objects in indicator when deinitializing in this code:

when switching TF I get journal entry: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 2 objects of type CChartObjectLabel left

if uncommented in OnInit() the creation of text labels (CChartObjectLabel), then everything will work correctly

I pass a pointer to theCreateLabel() function, butI can'tdelete it later inOnDeinit()

It creates a new object l. And it's not deleted.
 
Artyom Trishkin:
A new l object is created. And it is not deleted.

logically

But the scope ofCChartObjectLabel *LabelUP,*LabelDN; variables is global?

So I can modify the variable at any point in the code?

I pass a pointer to the CreateLabel() function, why do I create a new copy?

imho, it's not working correctly.

HH: If I create objects in OnInit() and then work with them in CreateLabel() (that is, I create the objects separately and work with them by pointer), everything will work correctly - but I do not remember a case in other compilers to pass a pointer to a function to create a new object - a pointer, he is a pointer!

 
Igor Makanu:

logically

but my scope is global? - it means i can modify a variable in any part of my code ?

I pass a pointer to CreateLabel(), why do I get a new copy?

Imho, it doesn't work correctly.

By reassigning a pointer to a new object, we lose the previous object to which the reassigned pointer pointed.
 
Igor Makanu:

logically

But the scope ofCChartObjectLabel *LabelUP,*LabelDN; variables is global?

So I can modify the variable at any point in the code?

I pass a pointer to the CreateLabel() function, why do I create a new copy?

Imho, it doesn't work correctly

new has to be removed. There are already objects and pointers to them.
 
Artyom Trishkin:
Reassigning a pointer to a new object, we loose the previous object, which was pointed by the reassigned pointer.

no, a pointer is a pointer, in MQL it's a descriptor, not the point - but it's not correct to create a new copy of the object, this works correctly now:

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
CChartObjectLabel *LabelUP,*LabelDN;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   LabelUP=new CChartObjectLabel;
   LabelDN=new CChartObjectLabel;
   SetLabel(LabelUP,"LabelUP",0);
   SetLabel(LabelDN,"LabelDN",25);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete LabelUP;
   delete LabelDN;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   return(rates_total);

  }
//+------------------------------------------------------------------+
void SetLabel(CChartObjectLabel *l,string name,int y)
  {
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }
//+------------------------------------------------------------------+

but if you follow your logic, then this code will also create a copy of object l in the function SetLabel() - i passed a pointer, not a reference?


Artyom Trishkin:
new should be removed. The objects already exist and so do the pointers to them.

the question is not how to solve the problem, but why in the global scope of the variableCChartObjectLabel *LabelUP,*LabelDN;- lost the pointer!

 
Igor Makanu:

no, a pointer is a pointer, in MQL it's a descriptor, not the point - but it's not correct to create a new copy of the object, this works correctly now:

but if you follow your logic, then this code will also create a copy of object l in the function SetLabel() - I passed a pointer, not a reference?

No. Here l is a parameter of the method through which we pass the needed pointer. Everything is fine here. The pointer here stays on the earlier created object. Here we don't create a new object and reassign the pointer to it with the loss of the previous object.
 
Artyom Trishkin:
No. Here l is the method parameter through which we pass the needed pointer. Everything is ok here. The pointer here stays on the earlier created object. Here we don't create a new object and reassign the pointer to it with the loss of the previous object.

it still doesn't work correctly

these "pointers" in MQL are made to work in the scope of the class, I don't want to create a class, I declare a global pointer and then pass it to any function, and the fact that in this function I create a descriptor of the object is not the reason to destroy the object upon exiting the local scope of the function

I'm a little busy right now, but I need to make test examples without graphics - I think the same thing will happen if you entered the function with a pointer with POINTER_INVALID value, you will exit with the same POINTER_INVALID , by reference, everything will work correctly, but it seems you can't pass a pointer with POINTER_INVALID by reference - there will be an error accessing the pointer

 
Igor Makanu:

everything doesn't work correctly anyway

these "pointers" in MQL are made to work in the scope of the class, I don't want to create a class, I just drill and declare a pointer in the global scope, then pass it to any function and the fact that I create an object handle in this function is not the reason to destroy the object upon exiting the local scope of the function

I think it will be the same problem, if you come in with POINTER_INVALID value in this function, you will exit with the same POINTER_INVALID value , by reference, everything will work correctly, but it seems that you can not pass a POINTER_INVALID value in this function - there will be an error when accessing the pointer

Exactly the object is not destructed. After a new object is created inside the method, we already have two objects. And there is only one pointer - it was passed to the method as a formal parameter. Thus we lose the pointer to one of the objects.
 

I was surprised to find that it was possible to declare typedef with a pointer to a template function.
However, the happiness did not last long.

template<typename T>
typedef bool (* callback)(T &);

template<typename T>
bool ff(T &){
   return true;
}

bool ff(int &){
   return true;
}


void OnStart(){
   int a;
   ff(a);
   
   callback<int> f_ptr_0 = ff;     //'<' - unexpected token     
   callback f_ptr_1 = ff;          //'ff' - function must have a body   
   callback f_ptr_2 = ff<int>;     //'ff<int>' - cannot resolve function address  //'ff<int>' - type mismatch   
}


Is typedef with a pointer to a template function a planned feature?

 
One more bug in the typedef garden:
typedef void (* callback)(int &);

template<typename T>
void ff(T &){}


void OnStart(){
   int a = 0;
   //ff(a);                     //  если раскомментировать, то работает
   
   callback f_ptr = ff<int>;    //  'ff<int>' - function must have a body
   f_ptr(a);
}

When working with typedef, using a template function with explicit specialisation does not generate code for that template