Bibliotheken: CDictionary - Seite 2

 

Ich habe einen Fehler in CDictionary entdeckt. Wenn Sie die Reset-Methode verwenden, wird das CList-Objekt in m_data gelöscht. Nachfolgende Aufrufe anderer Methoden, die den Punkt aus dem Wörterbuch holen, erhalten einen fehlerhaften Zeiger zurück. Beispiel:


#include "Dictionary.mqh"

void OnStart()
{
   CDictionary d;
   d.Set("key", 1);
   d.Reset();
   Print(d.Contains<int>("key"));
}


Ich würde den folgenden Fix für alle Methoden vorschlagen, die den Key-Hash verwenden, um auf ein CList-Objekt aus dem m_data-Array zuzugreifen.


template<typename T>
bool CDictionary::Contains(string key)
  {
   bool res=false;
   T value=NULL;
   int index=Index(Hash(key+typename(T)));
   if(CheckPointer(m_data[index]) == POINTER_INVALID)
      m_data[index] = new CList;
   CList *list=m_data[index];
   if(CheckPointer(list))
     {
      CDictionaryEntryBase *model=new CDictionaryEntry<T>(key,value);
      if(CheckPointer(list.Search(model)))
         res=true;
      delete model;
     }
   return res;
  }
 
nicholi shen:

Ich habe einen Fehler in CDictionary entdeckt. Wenn Sie die Reset-Methode verwenden, wird das CList-Objekt in m_data gelöscht. Nachfolgende Aufrufe anderer Methoden, die den Punkt aus dem Wörterbuch holen, erhalten einen fehlerhaften Zeiger zurück. Beispiel:



Ich würde die folgende Korrektur für alle Methoden vorschlagen, die den Schlüssel-Hash verwenden, um auf ein CList-Objekt aus dem m_data-Array zuzugreifen.


Danke Nicoli Shen. Ihre Lösung ist die "sicherere" Lösung. Allerdings kann ich das Problem nicht reproduzieren.

Eine andere Sache, die mich in diesem Zusammenhang stört: ein Objektzeiger sollte einen Nullwert akzeptieren können. m_data ist ein dynamisches Array, also sollte es Null zurückgeben, wenn ein nicht gefüllter Index aus dem Array abgerufen wird oder das gespeicherte Element gelöscht wird. Das Speichern von Daten aus m_data in CList* ohne vorherige Überprüfung des Zeigers wird auch bei anderen Methoden wie Get() und Delete() durchgeführt, so dass die obigen Testskripte ebenfalls fehlschlagen sollten, wenn dieses Problem besteht. Eine einfache Zuweisung zwischen einem Zeiger und einem anderen kann ohne Zeigerzugriffsfehler durchgeführt werden, selbst wenn das Objekt, auf das der l-Wert zeigt, bereits gelöscht ist:

#include <Object.mqh>
//+------------------------------------------------------------------+
//| Skript-Programmstartfunktion|
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   CObject *obj = new CObject();
   delete obj;
   CObject *obj1 = obj; //keine Fehler beim Zugriff auf ungültige Zeiger
  }
//+------------------------------------------------------------------+

Das Problem kann auf das obige Beispiel reduziert werden. Aber in diesem Fall gibt es keine Zeigerfehler. Ich bin neugierig, weil ich mich daran erinnere, dass ich das gleiche Problem in einem früheren Build hatte, das schnell gepatcht wurde.

Ich verwende derzeit MT5 Build 1932, aber lassen Sie mich wissen, wenn ich etwas übersehen habe.

[Gelöscht]  

Ich habe diese Fehlermeldung:


'Key' - unerwartetes Token, wahrscheinlich fehlt der Typ? Dictionary.mqh 39 23

'Key' - Funktion ist bereits definiert und hat einen anderen Typ Dictionary.mqh 39 23

siehe Deklaration von 'CDictionaryEntryBase::Key' Dictionary.mqh 20 22



Ich versuche, mit Build 3320 zurechtzukommen.

 
Sunfire #:

Ich habe diese Fehler:


'Key' - unerwartetes Token, wahrscheinlich fehlt der Typ? Dictionary.mqh 39 23

'Key' - Funktion ist bereits definiert und hat einen anderen Typ Dictionary.mqh 39 23

siehe Deklaration von 'CDictionaryEntryBase::Key' Dictionary.mqh 20 22



Ich versuche, mit Build 3320 zurechtzukommen.

Versuchen Sie, das Schlüsselwort "void" vor die Klassenmethode zu setzen
 
Dieser Code demonstriert eine hervorragende Funktionalität und nutzt die CObject-Vererbung, was eine nahtlose Integration mit CArray-Strukturen innerhalb des Wörterbuchs ermöglicht.
 
Zum Hinzufügen eines Integer-Arrays zum Wörterbuch:
#include "Include\Dictionary.mqh"
#include <Arrays\ArrayInt.mqh>
/

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   CDictionary my_dict;
   
   //--- arrayint zum Wörterbuch hinzufügen
   CArrayInt *my_arr_int= new CArrayInt;
   my_arr_int.Add(10);
   my_arr_int.Add(30);
   my_arr_int.Add(45);
   my_dict.Set<CObject*>("arrayint", my_arr_int);
   
   CArrayInt *res_arr;
   res_arr= my_dict.Get<CObject*>("arrayint");
   Print("intarray at 1= ",res_arr.At(1));
//---
   return(INIT_SUCCEEDED);
  }