Structure Speicherfehler

Für allgemeine Fragen zur Programmierung mit PureBasic.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Structure Speicherfehler

Beitrag von Skiller »

Hallo Leute,
warum Speicherfehler bei R_Nr.i ? Beii R_Nr.b oder .w geht´s. Was hab ich übersehen? :?
Danke !!!!

Code: Alles auswählen

EnableExplicit
Define.i i, j
;----------------------
Structure s_Rechnung
  R_Nr.i                ;R_Nr.(i,f)   funzt nicht!!!! warum??????  
  Menge.i
  Art.s
  Preis.f
EndStructure  
Dim Rechnung.s_Rechnung(0)

Structure s_Kunde
  K_Nr.i
  Name.s
  Alter.i
  ;---------------------
  Rechnung.s_Rechnung[0]   
EndStructure
Dim Kunden.s_Kunde(0)
;---------------------------------  
For i = 0 To 3
  If ArraySize(Rechnung.s_Kunde()) < j
     ReDim Kunden.s_Kunde(i)
  EndIf
  For j = 0 To 3  
    If ArraySize(Rechnung.s_Rechnung()) < j
       ReDim Rechnung.s_Rechnung(j)
    EndIf
    Kunden.s_Kunde(i)\Rechnung[j]\R_Nr = i   ; hier steigt er aus!!
    Debug Str(i)+", "+Str(j)+",      "+Str(Kunden.s_Kunde(i)\Rechnung[j]\R_Nr)
  Next j
  Debug "-----------------------" 
Next i 
Gruß Skiller
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Structure Speicherfehler

Beitrag von NicTheQuick »

Eigentlich müsste PB in Zeile 22 meckern:

Code: Alles auswählen

Rechnung.s_Kunde()
Die Struktur s_Kunde gehört ja nicht zu Rechnung(), sondern Rechnung() wurde vorher schon mit s_Rechnung als Struktur definiert.

Im Übrigen macht dein Code auch wenig Sinn. Wozu überhaupt dieses If?

Code: Alles auswählen

If ArraySize(Rechnung()) < j
Immerhin ist 'j' an der Stelle immer 0.

Dann greifst du auf 'Kunden(i)\Rechnung[j]\R_Nr', obwohl das ein leeres Array ist. Rechnung() dahingegen wird nur mit Redim vergrößert. Das wirkt sich aber nicht auf das statische Rechnungs[]-Array innerhalb der s_Kunde-Struktur aus.

Was du machen willst, ist wohl er sowas hier:

Code: Alles auswählen

EnableExplicit
Define.i i, j
;----------------------
Structure s_Rechnung
	R_Nr.i
	Menge.i
	Art.s
	Preis.f
EndStructure 

Structure s_Kunde
	K_Nr.i
	Name.s
	Alter.i
	;---------------------
	Array Rechnung.s_Rechnung(0)
EndStructure
Dim Kunden.s_Kunde(0)
;--------------------------------- 
For i = 0 To 3
	If ArraySize(Kunden()) < i
		ReDim Kunden(i)
	EndIf
	For j = 0 To 3 
		If ArraySize(Kunden(i)\Rechnung()) < j
			ReDim Kunden(i)\Rechnung(j)
		EndIf
		Kunden(i)\Rechnung(j)\R_Nr = i   ; hier steigt er aus!!
		Debug Str(i)+", "+Str(j)+",      "+Str(Kunden(i)\Rechnung(j)\R_Nr)
	Next j
	Debug "-----------------------"
Next i 
Benutzeravatar
Kiffi
Beiträge: 10725
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Structure Speicherfehler

Beitrag von Kiffi »

ich arbeite lieber mit LinkedLists anstelle von Arrays:

Code: Alles auswählen

EnableExplicit

Structure s_Rechnung
  R_Nr.i      
  Menge.i
  Art.s
  Preis.f
EndStructure  

Structure s_Kunde
  K_Nr.i
  Name.s
  Alter.i
  List Rechnung.s_Rechnung()
EndStructure

NewList  Kunde.s_Kunde()

AddElement(Kunde())

Kunde()\Name = "Skiller"

AddElement(Kunde()\Rechnung())

Kunde()\Rechnung()\Menge = 1
Kunde()\Rechnung()\Art   = "PB-Support"
Kunde()\Rechnung()\Preis = 999.9

ForEach Kunde()
  
  Debug "Kunde: " + Kunde()\Name
  
  ForEach Kunde()\Rechnung()
    
    Debug "Menge: " + Str(Kunde()\Rechnung()\Menge)
    Debug "Art: "   + Kunde()\Rechnung()\Art
    Debug "Preis: " + StrF(Kunde()\Rechnung()\Preis, 2)
    
  Next
  
Next
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Structure Speicherfehler

Beitrag von NicTheQuick »

Außerdem sollte man Preise nicht mit Fließkommazahlen angeben, sondern lieber ganzzahlig und dann in Cent.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Re: Structure Speicherfehler

Beitrag von Skiller »

Danke erstmal für die Antworten. ( welche meine eigentliche Frage aber gar nicht betreffen) Denn Im Grunde funzt das ja. Die Frage war: Warum Speicherfehler bei Structure Declaration R_Nr.i ? Bei R_Nr.b oder .w geht´s. Also das ".i" ist der knaxus. Stürzt er bei Euch an der selben Stelle ab? Bei R_Nr.b geht´s nämlich.
Die Struktur s_Kunde gehört ja nicht zu Rechnung(), sondern Rechnung() wurde vorher schon mit s_Rechnung als Struktur definiert
1. Stimmt! Sofern es nicht völlig Schräg gedacht ist, würde ich es auch so lassen, oder?
Außerdem sollte man Preise nicht mit Fließkommazahlen angeben, sondern lieber ganzzahlig und dann in Cent.
2. Zeig mal Beispiel
Im Übrigen macht dein Code auch wenig Sinn. Wozu überhaupt dieses If?If ArraySize(Rechnung()) < j
3. Weil er sonst jedesmal ein sinnloses Redim versuchen würde. Man kann es natürlich auch weg lassen.
Eigentlich müsste PB in Zeile 22 meckern: Rechnung.s_Kunde()
4. tut er aber nicht!
Array Rechnung.s_Rechnung(0)
5. Jetzt meckert er. (zumindest bei mir)
Dann greifst du auf 'Kunden(i)\Rechnung[j]\R_Nr', obwohl das ein leeres Array ist
6. Muss ja leer sein, wenn man von fehlerhaften Voraussetzungen wie o. A. ausgeht.
Rechnung() dahingegen wird nur mit Redim vergrößert. Das wirkt sich aber nicht auf das statische Rechnungs[]-Array innerhalb der s_Kunde-Struktur aus.
7. :?: Gruß Skiller
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Structure Speicherfehler

Beitrag von NicTheQuick »

Skiller hat geschrieben:Danke erstmal für die Antworten. ( welche meine eigentliche Frage aber gar nicht betreffen) Denn Im Grunde funzt das ja. Die Frage war: Warum Speicherfehler bei Structure Declaration R_Nr.i ? Bei R_Nr.b oder .w geht´s. Also das ".i" ist der knaxus. Stürzt er bei Euch an der selben Stelle ab? Bei R_Nr.b geht´s nämlich.
Das ist mehr oder weniger Zufall. Wenn du nur ein Byte oder wenige liest, dann liest du noch nicht weit genug in einen nicht allozierten Speicherbereich rein um einen Fehler zu erzeugen.
Skiller hat geschrieben:
Die Struktur s_Kunde gehört ja nicht zu Rechnung(), sondern Rechnung() wurde vorher schon mit s_Rechnung als Struktur definiert
1. Stimmt! Sofern es nicht völlig Schräg gedacht ist, würde ich es auch so lassen, oder?
Die Struktur oder den Typ einer Variable definiert man bei ihrer Definition und danach braucht man das nicht mehr anzugeben.
Skiller hat geschrieben:
Außerdem sollte man Preise nicht mit Fließkommazahlen angeben, sondern lieber ganzzahlig und dann in Cent.
2. Zeig mal Beispiel
Im Übrigen macht dein Code auch wenig Sinn. Wozu überhaupt dieses If?If ArraySize(Rechnung()) < j
3. Weil er sonst jedesmal ein sinnloses Redim versuchen würde. Man kann es natürlich auch weg lassen.
Naja, du nimmst einfach statt Floats Integer oder Long oder Quads, wie auch immer. Das Problem bei Floats sind die Ungenauigkeiten, die bei kleinen Werten vielleicht noch nicht auftauchen, aber z.B. ist 0.1 nicht gleich 0.1:

Code: Alles auswählen

f.f = 0.1
Debug f
Und gerade bei Geld sollte man doch eher Cent-genau arbeiten und ohne Ungenauigkeiten. Man muss dann eben nur beim Anzeigen etwas komplizierter denken:

Code: Alles auswählen

geld.q = 123	;1,23 Euro
Debug "Es sind " + geld  + " Cent."
Debug "Es sind " + Str(geld / 100) + "," + RSet(Str(geld % 100), 2, "0") + " Euro."
Skiller hat geschrieben:
Eigentlich müsste PB in Zeile 22 meckern: Rechnung.s_Kunde()
4. tut er aber nicht!
Ja, das ist dann ein Bug in PB. Müsste man gegebenenfalls mal melden.
Skiller hat geschrieben:
Array Rechnung.s_Rechnung(0)
5. Jetzt meckert er. (zumindest bei mir)
Welche PB-Version hast du denn? Die scheint dann schon etwas älter zu sein. Außerdem hilft mir "Meckern" nicht viel weiter. Welche Fehlermeldung kommt denn genau?
Skiller hat geschrieben:
Dann greifst du auf 'Kunden(i)\Rechnung[j]\R_Nr', obwohl das ein leeres Array ist
6. Muss ja leer sein, wenn man von fehlerhaften Voraussetzungen wie o. A. ausgeht.
Genau. In der Struktur von s_Kunde steht ja Rechnung[0], also ist kein einziges Element drin. Und Redim funktioniert damit ebenfalls nicht.
Skiller hat geschrieben:
Rechnung() dahingegen wird nur mit Redim vergrößert. Das wirkt sich aber nicht auf das statische Rechnungs[]-Array innerhalb der s_Kunde-Struktur aus.
7. :?:
Ganz einfach. Statische Arrays kann man nicht nachträglich vergrößern.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Re: Structure Speicherfehler

Beitrag von Skiller »

Hallo Nic,
sorry erst mal für die Verspätung. Also, ich will das Ding nicht weiter aufbauschen, aber nach wie vor hab ich keine laufende Array-Version. Die Kernfrage ist doch: Gehts mit verschachtelten StrukturArrays oder eben nicht. Kiffis Version ist ok, aber ich würde aus bestimmten Gründen lieber Arrays verwenden. (Bitte jetzt keine Diskussion warum) Als zwei Datentabellen wäre das im Grunde eine einfache Mutter-Kind Relation mit jeweils mehreren Feldern. Übertragen ist das ein einfaches zweidimensionales Array, nur halt ohne Felder. Die bekomme ich nun aber durch die Struktur realisiert. Somit ist mein Ansatz wohl richtig gewesen, die RechnungsArrayStruktur mit der KundenArrayStruktur zu verbinden. Wenn halt dieser blöde ".i" Fehler nicht gewesen wäre. Im Grunde hat der ganze Schwanz der Einzelheiten nicht viel Sinn, da es besser ist eine lauffähige Version mit diesem Gedankenansatz hineinzustellen. Das erspart viel Zeit und Schreiberei. Oder es funzt eben nicht. Ich kann mir einfach nicht vorstellen, dass das banale Progrämmchen eben an diesem besagten ".i" Fehler scheitert.>_<Oder es liegt eben an meinem Rechner. (Glaub ich aber auch nicht).
geld.q = 123 ;1,23 Euro
Debug "Es sind " + geld + " Cent."
Debug "Es sind " + Str(geld / 100) + "," + RSet(Str(geld % 100), 2, "0") + " Euro."
Danke, darauf wäre ich bestimmt nicht gekommen und erspart mir viel Zeit.
Skiller wrote:
Quote:
Array Rechnung.s_Rechnung(0)
5. Jetzt meckert er. (zumindest bei mir) Außerdem hilft mir "Meckern" nicht viel weiter. Welche Fehlermeldung kommt denn genau?
Code:

Code: Alles auswählen

Structure s_Kunde
  K_Nr.i
  Name.s
  Alter.i
  ;---------------------
  Array Rechnung.s_Rechnung[0]   ; hier meckert er und sagt: " 'Dim' Syntax lautet: Dim Arrayname(nb)"
EndStructure
Welche PB-Version hast du denn?
PB 5.11 x(86), x(64) hab ich allerdings noch nicht probiert!.

Grüße Skiller
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Structure Speicherfehler

Beitrag von NicTheQuick »

Skiller hat geschrieben:Hallo Nic,
sorry erst mal für die Verspätung. Also, ich will das Ding nicht weiter aufbauschen, aber nach wie vor hab ich keine laufende Array-Version. Die Kernfrage ist doch: Gehts mit verschachtelten StrukturArrays oder eben nicht.
Ja, das geht, aber nicht so wie du denkst. Statische Arrays in Structures kann man eben nachträglich nicht mehr in der Größe ändern. Deshalb hab ich dir ja einen Code im zweiten Post in diesem Thread programmiert, der es so macht wie du es vorhattest, nur eben richtig.
Skiller hat geschrieben:Wenn halt dieser blöde ".i" Fehler nicht gewesen wäre. Im Grunde hat der ganze Schwanz der Einzelheiten nicht viel Sinn, da es besser ist eine lauffähige Version mit diesem Gedankenansatz hineinzustellen. Das erspart viel Zeit und Schreiberei. Oder es funzt eben nicht. Ich kann mir einfach nicht vorstellen, dass das banale Progrämmchen eben an diesem besagten ".i" Fehler scheitert.>_<Oder es liegt eben an meinem Rechner. (Glaub ich aber auch nicht).
Es liegt auch nicht an deinem Rechner, denn den selben Fehler hab ich hier auch unter Linux. Und es ist auch klar, warum das passiert. Nämlich weil du in einen ungültigen Speicherbereich schreibst.

Also nochmal: Einfacher kann ich es fast nicht mehr machen. Da musst du schon mal selbst deinen Code Zeile für Zeile durchgehen und schauen, ob das alles so korrekt ist:

Code: Alles auswählen

EnableExplicit
Define.i i, j
;----------------------
Structure s_Rechnung
	R_Nr.i
	Menge.i
	Art.s
	Preis.f
EndStructure 
Dim Rechnung.s_Rechnung(0)

Structure s_Kunde
	K_Nr.i
	Name.s
	Alter.i
	;---------------------
	Rechnung.s_Rechnung[0]   
EndStructure
Dim Kunden.s_Kunde(0)

For i = 0 To 3
	Debug "j = " + j		;j ist an dieser Stelle zuerst 0, dann 4 wegen der For-Schleife in Zeile 26
	If ArraySize(Rechnung.s_Kunde()) < j	;Rechnung() hat in Zeile 10 noch den Typ s_Rechnung, warum jetzt s_Kunde?
		ReDim Kunden.s_Kunde(i)				;Warum änderst du die Größe von Kunden(), wenn eine Zeile drüber etwas von Rechnung() steht?
	EndIf
	For j = 0 To 3 
		If ArraySize(Rechnung.s_Rechnung()) < j		;Dieses If ist soweit korrekt. Wenn es zu wenige Elemente in Rechnung() gibt, erhöhe sie
			ReDim Rechnung.s_Rechnung(j)
		EndIf
		Kunden.s_Kunde(i)\Rechnung[j]\R_Nr = i   ;In Zeile 28 hast du die Größe von Rechnung() angepasst,
		                                         ;Kunden(i)\Rechnung[] hat aber immer noch 0 Elemente und das wird sich auch nicht ändern
		Debug Str(i)+", "+Str(j)+",      "+Str(Kunden.s_Kunde(i)\Rechnung[j]\R_Nr)
	Next j
	Debug "-----------------------"
Next i 
Wenn du genauer schaust, wird auch Rechnung() nie irgendwo beschrieben oder ausgelesen. Das Array wird nur in der Größe geändert. Das statische Rechnung[]-Array innerhalb der Kunden-Struktur wird allerdings beschrieben und gelesen, allerdings mit ungültigen Indices, da es von Anfang an 0 Elemente hat, so wie es in Zeile 17 definiert ist. Dass also irgendwann ein Speicherfehler auftritt und der noch mit der Größe des Typs von R_Nr zu tun hat ist eher Zufall. Eigentlich sollte es bei egal welchem Typ einen Fehler geben.
Skiller hat geschrieben:
Skiller wrote:
Quote:
Array Rechnung.s_Rechnung(0)
5. Jetzt meckert er. (zumindest bei mir) Außerdem hilft mir "Meckern" nicht viel weiter. Welche Fehlermeldung kommt denn genau?
Code:

Code: Alles auswählen

Structure s_Kunde
  K_Nr.i
  Name.s
  Alter.i
  ;---------------------
  Array Rechnung.s_Rechnung[0]   ; hier meckert er und sagt: " 'Dim' Syntax lautet: Dim Arrayname(nb)"
EndStructure
Welche PB-Version hast du denn?
PB 5.11 x(86), x(64) hab ich allerdings noch nicht probiert!.
Schau mal genau hin. ;) Stichwort "Klammern".

Ich hoffe du hast es mittlerweile verstanden, falls nicht, schau dir meinen Code bitte so oft an, bis du es verstehst. Und frag dich auch, wieso du in deinem Code zwei Arrays für die Rechnungen hast. Einmal in Zeile 10 und einmal in Zeile 17. Das ist doch schon von vornerein unlogisch, findest du nicht?
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Re: Structure Speicherfehler

Beitrag von Skiller »

oh, diese Klammern :angry:
dumme Sache. Als Struktur wäre das super gewesen. Aber is eben nich :(
Auf jeden Fall Danke!!!! erstmal. Werd noch mal alles durchdenken. Bin zwar schon ne Weile bei, aber kann nur Schubweise proggen. Werd mich also noch mal ranmachen.

so long... Skiller
Antworten