Hello,
I've been making an indicator and I see this issue in the Experts tab of X undeleted dynamic objects found: x objects of class A... So after reading some posts and this article https://www.mql5.com/en/articles/28 I still don't understand how it works. From my understanding if I don't use pointers I shouldn't have any problems of this type. So I created a simple indicator to see if I could understand it better but now I am even more confused.
I have a class CObjectA that has a string, a CObjectB class that has an object of type CObjectA and finally a CObjectArray that has an array of CObjectB. Why is there so much memory leaked? I don't use pointers, shouldn't all those objects be deleted?
Here the code and the print. I didn't create the deconstructors cause there was no difference because I can't delete any object if it's not a pointer, but I tried just in case and the result was the same:
Print:
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 26 undeleted dynamic objects found:
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 1 object of class 'CObjectArray'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 10 objects of class 'CObjectB'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 15 objects of class 'CObjectA'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 896 bytes of leaked memory found
As you can see we have 1 undeleted of CObjectArra. 10 of CObjectB which I guess are 5 of the default constructor and 5 when I do the new in the other constructor? And the 15 of CObjectA that I suppose happens the same as with the CObjectB but we have to add the new done in the CObjectB constructor with parameters? I'm really lost here.
Sorry for my ignorance, any help I'll appreciate.
Hello,
I've been making an indicator and I see this issue in the Experts tab of X undeleted dynamic objects found: x objects of class A... So after reading some posts and this article https://www.mql5.com/en/articles/28 I still don't understand how it works. From my understanding if I don't use pointers I shouldn't have any problems of this type. So I created a simple indicator to see if I could understand it better but now I am even more confused.
I have a class CObjectA that has a string, a CObjectB class that has an object of type CObjectA and finally a CObjectArray that has an array of CObjectB. Why is there so much memory leaked? I don't use pointers, shouldn't all those objects be deleted?
Here the code and the print. I didn't create the deconstructors cause there was no difference because I can't delete any object if it's not a pointer, but I tried just in case and the result was the same:
Print:
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 26 undeleted dynamic objects found:
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 1 object of class 'CObjectArray'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 10 objects of class 'CObjectB'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 15 objects of class 'CObjectA'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 896 bytes of leaked memory found
As you can see we have 1 undeleted of CObjectArra. 10 of CObjectB which I guess are 5 of the default constructor and 5 when I do the new in the other constructor? And the 15 of CObjectA that I suppose happens the same as with the CObjectB but we have to add the new done in the CObjectB constructor with parameters? I'm really lost here.
Sorry for my ignorance, any help I'll appreciate.
You are using 'new' operator, so you are using pointers.
CObjectA a1=new CObjectA("as") -> a1 points to the object of type CObjectA that contains the string "as"
CObjectA *a2=new CObjectA("as") -> a2 points to the object of type CObjectA that contains the string "as"
So basically the same? I thought that the * was used to be able to not create again the same object. Let me illustrate my thoughts and why I said pointer:
class CObjectA{ public: string s; CObjectA(){}; CObjectA(string _s){ s=_s; } ~CObjectA(){} }; CObjectA arr[1]; int OnInit() { CObjectA a1=new CObjectA("asd"); arr[0]=a1; //This would create a copy of a1 inside the array so even if a1 is reused the information of array[0] should not be changed CObjectA *a2=&arr[0]; //a2 is referencing array[0] so any change I do in a2 will be reflected in the array a2.s="be"; a1.s="qwe"; Print(a2.s); Print(a1.s); Print(arr[0].s); return(INIT_SUCCEEDED); }Print:
be
qwe
be
So that is why I said i didn't use pointers as I see a2 as a pointer but not a1. Although as you say a1 is a pointer to an object but not the same as a2. I don't know if I expressed well, it seems so confusing.
So now I'm questioning if I have been doing it wrong everytime and when using new, I should always have used *. Because although no errors are found when compiling I can't delete a1 if it has not * when creating it. It gives me error. In this example if I do delete a1 this error will pop up when compiling:
'a1' - parameter conversion not allowed TestMemory2.mq5 40 11
V*Cdbg_heap_obj_trace::operator-(V*) checker_for_memory_leaks.mqh 75 7
'operator-' - illegal operation use TestMemory2.mq5 40 4
'dbg_heap_obj_trace' - object pointer expected TestMemory2.mq5 40 4
But if I use * for a1 it will delete it and no memory leaks will be found so that's why I think I've been doing it wrong all the time. But if this creates problems why gives no compile errors nor warnings? Shouldn't every new have a * and then a delete to avoid memory leaks? In other OOP languages I've never used * when creating a new object that's is why is so confusing for me, I was taught doing it that way. So now I don't know if I've been doing it wrong all time or is a mql5 thing.
Thank you.

- www.mql5.com
But the problem I think I have is more a comprehensive one for now as I'm not totally understand it, though this will help me a lot when I finally understand it. So thank you.
I also read in other post that avery new must have a delete but as I replied to Alain Verleyen I was using new without *, as my first example shows, and when I do that it will give me an error if I try to delete it. I've always done it in other oop languages, was taught doing it like that, and didn't see any errors so now I don't know if I've been doing it wrong all time or is just how mql5 works.
Again, thank youfor the amazing resource!
Not sure if I understand. Again, sorry for my ignrance but I thought that when I don't use the * I'm not using "pointers". So now, I'm more confused, let me show an example.
CObjectA a1=new CObjectA("as") -> a1 points to the object of type CObjectA that contains the string "as"
CObjectA *a2=new CObjectA("as") -> a2 points to the object of type CObjectA that contains the string "as"
So basically the same? I thought that the * was used to be able to not create again the same object. Let me illustrate my thoughts and why I said pointer:
Print:
be
qwe
be
So that is why I said i didn't use pointers as I see a2 as a pointer but not a1. Although as you say a1 is a pointer to an object but not the same as a2. I don't know if I expressed well, it seems so confusing.
So now I'm questioning if I have been doing it wrong everytime and when using new, I should always have used *. Because although no errors are found when compiling I can't delete a1 if it has not * when creating it. It gives me error. In this example if I do delete a1 this error will pop up when compiling:
'a1' - parameter conversion not allowed TestMemory2.mq5 40 11
V*Cdbg_heap_obj_trace::operator-(V*) checker_for_memory_leaks.mqh 75 7
'operator-' - illegal operation use TestMemory2.mq5 40 4
'dbg_heap_obj_trace' - object pointer expected TestMemory2.mq5 40 4
But if I use * for a1 it will delete it and no memory leaks will be found so that's why I think I've been doing it wrong all the time. But if this creates problems why gives no compile errors nor warnings? Shouldn't every new have a * and then a delete to avoid memory leaks? In other OOP languages I've never used * when creating a new object that's is why is so confusing for me, I was taught doing it that way. So now I don't know if I've been doing it wrong all time or is a mql5 thing.
Thank you.
Yes ideally the compiler should throw an error, but it doesn't.
I was not precise enough in my first answer. Your variables, are not pointers. But as you initialized them using "new", the memory is set on the heap and so should be "delete", but as you don't have pointers you can't.
You should not mix objects and pointers.
If you don't use pointer "*", then don't use "new".
If you use pointer "*', use "new" AND "delete", (or reference &).
Yes ideally the compiler should throw an error, but it doesn't.
I was not precise enough in my first answer. Your variables, are not pointers. But as you initialized them using "new", the memory is set on the heap and so should be "delete", but as you don't have pointers you can't.
You should not mix objects and pointers.
If you don't use pointer "*", then don't use "new".
If you use pointer "*', use "new" AND "delete".
class CObjectA{ public: string s; CObjectA(){}; CObjectA(string _s){ s=_s; } }; class CObjectB{ public: CObjectA *a; CObjectB(){} CObjectB(string s){ a=new CObjectA(s); } ~CObjectB(){ delete a; } }; class CObjectArray{ public: CObjectB *o[5]; string s; CObjectArray(){} CObjectArray(string _s){ s=_s; for(int i=0; i<5; i++) o[i]=new CObjectB(IntegerToString(i)); } ~CObjectArray(){ for(int i=0; i<5; i++) delete o[i]; } }; CObjectArray *array; int OnInit() { array=new CObjectArray("array"); Print(array.s); for(int i=0;i<5;i++) Print(array.o[i].a.s); return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ delete array; }
class CObjectA{ public: string s; CObjectA(){}; CObjectA(string _s){ s=_s; } }; class CObjectB{ public: CObjectA a; CObjectB(){} CObjectB(string s){ a=CObjectA(s); } }; class CObjectArray{ public: CObjectB o[5]; string s; CObjectArray(){} CObjectArray(string _s){ s=_s; for(int i=0; i<5; i++) o[i]=CObjectB(IntegerToString(i)); } }; CObjectArray array; int OnInit() { array=CObjectArray("array"); Print(array.s); for(int i=0;i<5;i++) Print(array.o[i].a.s); return(INIT_SUCCEEDED); }
In the first one I am using new to create the objects which makes me have to implement the deconstrucor of the classes that have pointers and delete the array in OnDeinit. On the other hand, the second example don't use pointers which makes it easier as you don't have to worry to delete the pointers once you are done. So, is there any case where I should be using new? Am I missing something? As I said I have not much experience with this and maybe there's something memory or efficiency related that I'm not taking into account.
The example given in https://www.mql5.com/en/book/oop/classes_and_interfaces/classes_new_delete_pointers is about drawing shapes but in https://www.mql5.com/en/book/oop/classes_and_interfaces/classes_inheritance they do exactly that without using new. I coded it to see if I could do different shapes and store them in an array and it worked not using new without any problem. So i can't see any difference.
Again thank you for all the help you are giving me!

- www.mql5.com
Thank you, I understand now. But I still can't figure out why I should use new then. It makes things more complicated, at least from my ignorant point of view. Let me explain myself with these 2 examples that do exactly the same:
In the first one I am using new to create the objects which makes me have to implement the deconstrucor of the classes that have pointers and delete the array in OnDeinit. On the other hand, the second example don't use pointers which makes it easier as you don't have to worry to delete the pointers once you are done. So, is there any case where I should be using new? Am I missing something? As I said I have not much experience with this and maybe there's something memory or efficiency related that I'm not taking into account.
The example given in https://www.mql5.com/en/book/oop/classes_and_interfaces/classes_new_delete_pointers is about drawing shapes but in https://www.mql5.com/en/book/oop/classes_and_interfaces/classes_inheritance they do exactly that without using new. I coded it to see if I could do different shapes and store them in an array and it worked not using new without any problem. So i can't see any difference.
Again thank you for all the help you are giving me!
If you don't know when to use pointers, just don't use them. When you will encounter a situation where you need a pointer, you will understand why.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello,
I've been making an indicator and I see this issue in the Experts tab of X undeleted dynamic objects found: x objects of class A... So after reading some posts and this article https://www.mql5.com/en/articles/28 I still don't understand how it works. From my understanding if I don't use pointers I shouldn't have any problems of this type. So I created a simple indicator to see if I could understand it better but now I am even more confused.
I have a class CObjectA that has a string, a CObjectB class that has an object of type CObjectA and finally a CObjectArray that has an array of CObjectB. Why is there so much memory leaked? I don't use pointers, shouldn't all those objects be deleted?
Here the code and the print. I didn't create the deconstructors cause there was no difference because I can't delete any object if it's not a pointer, but I tried just in case and the result was the same:
class CObjectA{ public: string s; CObjectA(){}; CObjectA(string _s){ s=_s; } }; class CObjectB{ public: CObjectA a; CObjectB(){} CObjectB(string s){ a=new CObjectA(s); } }; class CObjectArray{ public: CObjectB o[5]; CObjectArray(){} CObjectArray(string s){ for(int i=0; i<5; i++) o[i]=new CObjectB(s); } }; CObjectArray array; int OnInit() { array=new CObjectArray("asd"); for(int i=0;i<5;i++) Print(array.o[i].a.s); return(INIT_SUCCEEDED); }
Print:
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:36.525 TestMemory (AUDJPY,H1) asd
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 26 undeleted dynamic objects found:
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 1 object of class 'CObjectArray'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 10 objects of class 'CObjectB'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 15 objects of class 'CObjectA'
2024.12.07 15:26:46.349 TestMemory (AUDJPY,H1) 896 bytes of leaked memory found
As you can see we have 1 undeleted of CObjectArra. 10 of CObjectB which I guess are 5 of the default constructor and 5 when I do the new in the other constructor? And the 15 of CObjectA that I suppose happens the same as with the CObjectB but we have to add the new done in the CObjectB constructor with parameters? I'm really lost here.
Sorry for my ignorance, any help I'll appreciate.