Possible bug in passing pointer (descriptor) of an object to a function by reference

 

I am not absolutely sure if there is some method of passing objects I am not aware of (or I am doing something silly wrong) but extremely erratic behaviour in the contents of an object passed to a function leads me to believe this is a bug..

 

When declaring a pointer in a block of code, you can access variables and sub objects normally as if you are directly interacting with the object. However, when this pointer is passed to a function, the data and more importantly the sub objects, arrays of sub objects etc, begin to do strange things. The debugger will start to show contents of those same variables within this object in the main code that are clearly not correct (my guess is they are actually pointing to the wrong memory locations once within the function). Oddly enough just to make the problem even more confusing, the actual printed output differs significantly from what the debugger is reading at that location of the buffer! the ouput will be something like 3, 4, 5, 6, 7, 8, 9, 10, 20 as the debugger will be something like 0, 35, 600032, 0 etc. Arrays and sub objects with arrays start to do even stranger things where the dimensions of the array change when passed to the funtion. The debugger will claim for example block 1 of the array has 1 dimension, and block 2 has 4 dimensions, etc. This has resulted in a crash on a few occasions on my client.

 

It should be noted that if an actual object is passed to the function, this behaviour does not occur, and everything does exactly what its supposed to. I have tried to make a very simple example to demonstrate the problem, however I guess from this you can easily create sub objects etc.

#property link      "http://www.mql5.com"
#property version   "1.00"

class CItem
  {
   public:
   int a;      //internal variable
                     CItem(){Print(__FUNCTION__," Constructor");}
                    ~CItem(){Print(__FUNCTION__," Destructor");}
  };

void OnStart()
{
  CItem* array1[];
  
  int arraysize = 10;
  string output;
  
  int test;
  
  ArrayResize(array1,arraysize);
  
  for(int i = 0; i<arraysize; i++)
   {
   array1[i] = new CItem;
   array1[i].a=i;
   }
 
  printCItem(array1);
}


void printCItem(CItem &item[])
{
   int arraysize = ArraySize(item);
   for (int i = 0; i < arraysize; i++)
      Print(item[i].a);
}

 I can provide more examples if necessary. Hope this outlines the problem.

 

While I am on the topic, I realised another potential problem with dynamic memory. There doesnt appear to by any kind of check in metatrader to stop you from assigning unlimited amounts of dynamic memory in real time. This results in the computer completely freezing up. I realised this when creating multi dimensional dynamic arrays (by using the object in object trick). I know this is probably bad programming practise, but it does achieve the desired results. The danger however is it is very easy to accidently assign 10 gig of memory whence working in 3 or 4 dimensions, resulting in a lockup.

Using the Object Pointers in MQL5
  • 2010.04.16
  • MetaQuotes Software Corp.
  • www.mql5.com
By default, all objects in MQL5 are passed by reference, but there is a possibility to use the object pointers. However it's necessary to perform the pointer checking, because the object may be not initialized. In this case, the MQL5 program will be terminated with critical error and unloaded. The objects, created automatically, doesn't cause such an error, so in this sence, they are quite safe. In this article, we will try to understand the difference between the object reference and object pointer, and consider how to write secure code, that uses the pointers.
 
Metal10k:

I am not absolutely sure if there is some method of passing objects I am not aware of (or I am doing something silly wrong) but extremely erratic behaviour in the contents of an object passed to a function leads me to believe this is a bug..

 

When declaring a pointer in a block of code, you can access variables and sub objects normally as if you are directly interacting with the object. However, when this pointer is passed to a function, the data and more importantly the sub objects, arrays of sub objects etc, begin to do strange things. The debugger will start to show contents of those same variables within this object in the main code that are clearly not correct (my guess is they are actually pointing to the wrong memory locations once within the function). Oddly enough just to make the problem even more confusing, the actual printed output differs significantly from what the debugger is reading at that location of the buffer! the ouput will be something like 3, 4, 5, 6, 7, 8, 9, 10, 20 as the debugger will be something like 0, 35, 600032, 0 etc. Arrays and sub objects with arrays start to do even stranger things where the dimensions of the array change when passed to the funtion. The debugger will claim for example block 1 of the array has 1 dimension, and block 2 has 4 dimensions, etc. This has resulted in a crash on a few occasions on my client.

 

It should be noted that if an actual object is passed to the function, this behaviour does not occur, and everything does exactly what its supposed to. I have tried to make a very simple example to demonstrate the problem, however I guess from this you can easily create sub objects etc.

 I can provide more examples if necessary. Hope this outlines the problem.

 

While I am on the topic, I realised another potential problem with dynamic memory. There doesnt appear to by any kind of check in metatrader to stop you from assigning unlimited amounts of dynamic memory in real time. This results in the computer completely freezing up. I realised this when creating multi dimensional dynamic arrays (by using the object in object trick). I know this is probably bad programming practise, but it does achieve the desired results. The danger however is it is very easy to accidently assign 10 gig of memory whence working in 3 or 4 dimensions, resulting in a lockup.

Thank you.

We will check and fix it as soon as possible.