Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   komischer Fehler (http://www.expert-advisor.com/forum/showthread.php?t=5527)

ping 07.03.17 19:45

komischer Fehler
 
Hi,

habe hier einen echt komischen Fehler:

so läuft das Programm fehlerlos:
Code:

#property indicator_chart_window
#property strict
string Feld[6],Zeichenkette="0,1,2,3,4,5";
int init()
{ StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Alert(Feld[5]);
  return(0);
}
int start()
{ return(0);
}

wenn man aus der Zeichenkette ,5 löscht dann gibt's "array out of range":
Code:

#property indicator_chart_window
#property strict
string Feld[6],Zeichenkette="0,1,2,3,4";
int init()
{ StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Alert(Feld[5]);
  return(0);
}
int start()
{ return(0);
}

weiss jemand warum?
Das Feld[5] sollte doch da sein, wenn auch leer.

ciao ping

traderdoc 07.03.17 20:18

Dann würde ich einfach schreiben:

string Feld[];

traderdoc

ping 07.03.17 20:40

Zitat:

Dann würde ich einfach schreiben:

string Feld[];

traderdoc
nee, ist ja derselbe Fehler, nur jetzt zu Recht nachvollziehbar.

eine Lösung dafür ist ja einfach (wenn die Anzahl der Teilstrings nicht bekannt ist):

Code:

#property indicator_chart_window
#property strict
string Feld[],Zeichenkette="0,1,2,3,4";
int init()
{ if(StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld)>5)
    Alert(Feld[5]);
  else
    Alert("kein 5. Teilstring vorhanden");
  return(0);
}
int start()
{ return(0);
}

aber ich wundere mich nur, dass man ein Array mit seiner Elementenanzahl fest definiert und dann sind nach StringSplit nicht mehr alle Elemente vorhanden. Das ist halt komisch.

traderdoc 07.03.17 21:21

Ja was heißt da "nee", wenn Du im darauffolgenden Code
string Feld[] selber benutzt?

traderdoc

ping 08.03.17 00:29

Zitat:

Ja was heißt da "nee", wenn Du im darauffolgenden Code
string Feld[] selber benutzt?

traderdoc
versteh ich jetzt nicht.

meinst du "Alert(Feld[]);"

im Orginalcode wollte ich Feld[5] einer Variablen zuweisen.
NeueVariable[i]=Feld[5];
und da kam der "Array out of Range", weil teilweise (in einer Schleife aus einer Datei ausgelesen) kein 5.Teilstring in "Zeichenkette" vorhanden war.

Ich würde das (bis jemand eine logische Begründung abliefert warum das so sein muss) als "Bug" bezeichnen.

traderdoc 08.03.17 09:44

Dann probiere doch mal folgendes aus:

string Feld[6];

Alert(Feld[0]); // oder auch Index 1 bis 5

Was siehst Du da?

traderdoc

ping 16.03.17 16:43

Hi,

abschließend sei angemerkt:

egal wie man die Array-Variable Feld definiert

string Feld[]; oder
string Feld[1]; oder
string Feld[5];
string Zeichenkette="0,1,2";

nach dem Funktionsaufruf

StringSplit(Zeichenkette,StringGetCharacter(",",0) ,Feld);

wird für Feld neuer Speicher allokiert.

in diesem Fall hat Feld immer 3 Elemente. (sebst bei string Feld[1] wohlgemerkt)

ciao ping

Kronenchakra 16.03.17 22:59

Stringsplit
 
Jetzt hat mich das aber auch interessiert was da los ist mit dem StringSplit().
Also kleines Testscript gebaut und schon ist alles klar.
Das Array wird nicht ReAlloziert.
Ist es statisch zu klein, ergibt das einen Fehler.
Ist es statisch zu groß, passiert nix.
Das beste ist, das Array von Stringsplit() dynamisch allozieren zu lassen. :)
Hier das TestScript: Teste das Feld statisch: Feld[3], Feld[7] und dynamisch Feld[]
Code:

void OnStart()
{
  string Feld[];
  string Zeichenkette="0,1,2,3,4";
  Print("ArraySize is ",ArraySize(Feld));
  int count=StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Print("ArraySize is ",ArraySize(Feld));
  Print(count," Elements found");
  if(count<0)
      {
        Print("a *ERROR* oh Kurt, Array is too small!");
        return;
      }
  for(int i=0; i<count; i++)    // IndexMax = count-1
      Print(Feld[i]);
}

Ich denke das beseitigt alle Unklarheiten.

Grüße Otto

traderdoc 17.03.17 06:13

"Das Array wird nicht ReAlloziert.
Ist es statisch zu klein, ergibt das einen Fehler.
Ist es statisch zu groß, passiert nix."

Ja, was denn sonst!?

traderdoc

ping 17.03.17 12:11

Liste der Anhänge anzeigen (Anzahl: 3)
Hi traderdoc, hi Kronenchakra,

ich glaube wir arbeiten mit unterschiedlichen Builds die unterschiedlich arbeiten.
Also ich habe Build 1045

und da ergeben sich folgende Ergebnisse:

bei 1.:
Code:

void OnStart()
{
  string Feld[];
  string Zeichenkette="0,1,2,3,4";
  Alert("ArraySize is ",ArraySize(Feld));
  int count=StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Alert("ArraySize is ",ArraySize(Feld));
  Alert(count," Elements found");
  if(count<0)
      {
        Alert("a *ERROR* oh Kurt, Array is too small!");
        return;
      }
  for(int i=0; i<count; i++)    // IndexMax = count-1
      Alert(Feld[i]);
}http://www.expert-advisor.com/forum/...lFTkSuQmCCAA==http://www.expert-advisor.com/forum/...AASUVORK5CYIIA

Anhang 2739

bei 2.:
Code:

void OnStart()
{
  string Feld[1];
  string Zeichenkette="0,1,2,3,4";
  Alert("ArraySize is ",ArraySize(Feld));
  int count=StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Alert("ArraySize is ",ArraySize(Feld));
  Alert(count," Elements found");
  if(count<0)
      {
        Alert("a *ERROR* oh Kurt, Array is too small!");
        return;
      }
  for(int i=0; i<count; i++)    // IndexMax = count-1
      Alert(Feld[i]);
}

Anhang 2740

bei 3.:
Code:

void OnStart()
{
  string Feld[20];
  string Zeichenkette="0,1,2,3,4";
  Alert("ArraySize is ",ArraySize(Feld));
  int count=StringSplit(Zeichenkette,StringGetCharacter(",",0),Feld);
  Alert("ArraySize is ",ArraySize(Feld));
  Alert(count," Elements found");
  if(count<0)
      {
        Alert("a *ERROR* oh Kurt, Array is too small!");
        return;
      }
  for(int i=0; i<count; i++)    // IndexMax = count-1
      Alert(Feld[i]);
}

Anhang 2741

... und das ist genau wie von mir beschrieben, das Feld wird neu allokiert!

... oder habe ich vieleicht "Build 1045 extended vision" und wusste bisher gar nix davon?

ciao ping


http://www.expert-advisor.com/forum/...lFTkSuQmCCAA==

ping 17.03.17 13:25

Nachtrag:

Zitat:

Zitat von ping (Beitrag 38100)
... oder habe ich vieleicht "Build 1045 extended vision" und wusste bisher gar nix davon?

... visionen hab ich viele, aber in diesem (tiefen) Fall eher "version" ;)

Zitat:

Zitat von Kronenchakra (Beitrag 38095)
Ich denke das beseitigt alle Unklarheiten

... alles wieder offen! :cool:

Kronenchakra 17.03.17 13:27

Stringsplit()
 
Ist ja unglaublich :eek:
Ich habe es mit dem MT5 getestet.
Der druckt mit Print() auch von oben nach unten und nicht von unten nach oben.
Verwende das dynamische Array und alles ist gut.
Mit gewissen Eigenheiten muss man in MQL4/5 einfach leben.

Grüße Otto

traderdoc 17.03.17 18:51

Das " Ja, was denn sonst" bezog sich auf den logischen Normalfall. Der wiederum sollte sich aus dem Funktionsumfang der Array-Funktionen ergeben. Da es eine Funktion ArrayResize() gibt, die genau dafür vorgesehen ist, einem Array in seiner 1. Dimension die Größe vorzugeben, erschließt es sich mir nicht, wieso dann andere Funktionen ebenfalls zu Reallokationen führen. Das schafft unnötige Verwirrung und produziert Systemfehler, die wieder einmal sehr schwer erkennbar gewesen wären.

Aber gut, dann werden wir auf jeden Fall damit im MQL4 zu leben haben und danken offiziell dem @ping für die Aufdeckung dieses Bugs.

traderdoc


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:38 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum