[kein Bug] Invalid Memory Access bei AddElement()

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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

[kein Bug] Invalid Memory Access bei AddElement()

Beitrag von NicTheQuick »

Hi!

Bastel gerade an einem größeren Projekt und habe mir eine Laderoutine
gebastelt, die mehrere Elemente mit einer großen Struktur nacheinander
aus einer Datei einläd.

Um die Struktur einzulesen, benutze ich folgende allgemein gehaltene Routine:

Code: Alles auswählen

Procedure ReadStructure(FileID.l, *Var.AllTypes, *Struc.BYTE)
  Protected length.l
  
  While *Struc\b
    Select *Struc\b
      Case 'b' : *Var\b = ReadByte(FileID)      : *Var + 1
      Case 'c' : *Var\c = ReadCharacter(FileID) : *Var + 1
      Case 'w' : *Var\w = ReadWord(FileID)      : *Var + 2
      Case 'l' : *Var\l = ReadLong(FileID)      : *Var + 4
      Case 'f' : *Var\f = ReadFloat(FileID)     : *Var + 4
      Case 'd' : *Var\d = ReadDouble(FileID)    : *Var + 8
      Case 'q' : *Var\q = ReadQuad(FileID)      : *Var + 8
      Case 's'
        length = ReadLong(FileID)
        *Var\s = Space(length)
        ReadData(FileID, @*Var\s, length)
        *Var + 4
    EndSelect
    *Struc + 1
  Wend
EndProcedure
Das hier ist die Laderoutine:

Code: Alles auswählen

Procedure Sat_Load(File.s, Add.l = 0)
  Protected FileID.l
  If Add
    LastElement(Satellite())
  Else
    ClearList(Satellite())
  EndIf
  
  FileID = ReadFile(#PB_Any, File)
  If FileID
    a = ReadLong(FileID)
    While Eof(FileID) = 0 And a
      If AddElement(Satellite())
        ReadStructure(FileID, @Satellite(), @Struc_Satellite)
        a - 1
      EndIf
    Wend
    CloseFile(FileID)
  EndIf
EndProcedure
In der Zeile mit dem [c]AddElement(Satellite())[/c] kommt es nach
einigen Datensätzen, ca. 8 bis 10, zu einem Fehler und der Debugger
meldet "Invalid Memory Access". Kommentiere ich die nachfolgende Zeile
mit [c]ReadStructure(blabla)[/c] aus, funktioniert alles wunderbar, es
werden allerdings keine Daten in die Struktur eingelesen.

Bevor ich jetzt ein lauffähiges Beispiel poste, würde ich gerne wissen, ob
es mit [c]AddElement()[/c] schon ähnliche Probleme in der Beta gibt oder
nicht.

Danke!
Zuletzt geändert von NicTheQuick am 27.02.2006 21:26, insgesamt 1-mal geändert.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Auf den ersten Blick:
Wie sieht deine AllTypes-Struktur aus?
Deine erste Methode ist nicht allgemein, benutz da mal Unicode ;)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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

Beitrag von NicTheQuick »

Das ist meine Structure:

Code: Alles auswählen

Structure AllTypes
  StructureUnion
    b.b
    c.c
    w.w
    l.l
    f.f
    d.d
    q.q
    s.s
  EndStructureUnion
EndStructure
Allgemein galt eher für das Projekt. Da brauche ich kein Unicode.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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

Beitrag von NicTheQuick »

Die [c]ReadtStructure()[/c]-Funktion funktioniert übrigens tadellos. Wenn
ich ihr eine lokale Struktur übergebe und direkt mir Debug ein paar
Testwerte debugge, ist alles richtig.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Ich frag jetzt mal nur zur Sicherheit, hast du die LinkedList auch wirklich
mit dieser Struktur deklariert?
Wenn ja, scheints langsam wirklich ein Bug zu sein :roll: oder ich steh
genauso aufm Schlauch wie du <)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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

Beitrag von NicTheQuick »

Hier mal der komplette Code: Code (Ziel speichern unter...)
So viel ist es nicht. Die Hauptdatei wäre [c]Inc_Satellite.pbi[/c]. Wenn
noch noch was fehlt, nochmal melden.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Ganz einfach :) (Ne, musste lange suchen)
Entfern mal die StructureUnions aus deiner Struktur, also

Code: Alles auswählen

Structure Satellite
  Name.s            ; Satellitenname
  ;Teil 1
  Number.l          ; 03-07 Satellitennummer
  
  IntKennz_1.b      ; 10-11 Internationale Kennzeichnung (die beiden letzten Ziffern des Startjahres)
  IntKennz_2.w      ; 12-14 Internationale Kennzeichnung (Startnummer des Jahres)
  IntKennz_3.s      ; 15-17 Internationale Kennzeichnung (Stückbezeichnung)
  
  Epoche_y.c        ; 19-20 Epoche: Jahr (die beiden letzten Ziffern des Jahres)
  Epoche_d.d        ; 21-32 Epoche: Tag des Jahres mit Tagesbruchteil
  
  NDot.d            ; 34-43 Erste Zeitableitung der mittleren Bewegung (N-punkt) oder Ballistischer Koeffizient (je nach Ephemeriden-Typ)
  NDotDot.d         ; 45-42 Zweite Zeitableitung der mittleren Bewegung (N-punkt-punkt) (Dezimalpunkt wird unterstellt; leer falls unbekannt)
  
  ;StructureUnion  ; 54-61 BSTAR Reibungsterm bei GP4-Störungstheorie. Sonst Strahlungsdruck-Koeffizient.(Dez.punkt unterstellt)
    Reibungsterm.d 
    Strahlungsdruck.d
  ;EndStructureUnion
  
  Ephemeriden.c     ; 63-63 Ephemeriden-Typ
  
  Nummerierung.w    ; 65-68 Nummerierung der Two-Line-Elements
  
  ;Teil 2
  Inklination.d     ; 09-16 Inklination [Grad]
  Rektaszension.d   ; 18-25 Rektaszension aufsteigender Knoten (Knotenlage) [Grad]
  Exzentrizitaet.d  ; 27-33 Exzentrizität (Dezimalpunkt wird unterstellt)
  Perigaeumslage.d  ; 35-42 Perigäumslage [Grad]
  MidAnomalie.d     ; 44-51 Mittlere Anomalie [Grad]
  MidBewegung.d     ; 53-63 "Mittlere Bewegung" [Umläufe/Tag]
  AktUmlauf.l       ; 64-68 Nummer des aktuellen Umlaufs zur Epoche [Umläufe]
EndStructure
Dann läufts :)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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

Beitrag von NicTheQuick »

Ja, hab den Fehler mittlerweile schon selbst gefunden.
Die [c]StructureUnion[/c]s waren allerdings richtig. Falsch war folgende
Zeile. Da war ein "d" zuviel. So ist es richtig:

Code: Alles auswählen

Global Struc_Satellite.s = "slbwscddddcwddddddl"
Aber trotzdem Danke. Also kein Bug. Ich änder das mal im Titel.

Aber blöd ist trotzdem die Angabe des Fehlers. Anfangs hat er
[c]AddElement()[/c] markiert und den Fehler gebracht und dann hab ich
alles etwas umgestellt und dann war der Fehler bei [c]ReadStructure()[/c].
Aber es wäre ja wohl schlauer, wenn er die entsprechende Zeile in
[c]ReadStructure()[/c] markiert, die zuweit liest.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Komisch, beim entfernen eines 'd's gabs bei mir wieder Fehler, aber egal,
anscheinend läufts ja jetzt :)
Benutzeravatar
shadow
Beiträge: 189
Registriert: 23.03.2005 17:52
Wohnort: Lübeck

Beitrag von shadow »

Hi,

jetzt wo das angesprochen wird kann ich mich erinnern, dass ich auch Invalid Memory Access Fehler bei meinem SQLite Wrapper hatte. Damals dachte ich, dass es mit dem Funktionsaufruf wegen einem falsch gesetzten Zeiger was zu tun hatte oder so.
Hier mal mein Code der Callback:

Code: Alles auswählen

;- Struktur für einen Datensatz (max. 20 Spalten)
Structure SRecordSet
  StructureUnion
    Column.l[20]
    Record.s[20]
  EndStructureUnion
EndStructure
; Liste mit dem aktuellen ResultSet (aktuelle Datensätze)
NewList ResultSet.SRecordSet()
;************************************************************************
; Callback-Routine für die Datenbank.
;************************************************************************
Procedure.l DBCallback(*parg.s, argc.l, argv.l, col.l)
  ; PB meldet ab und zu einen Speicherzugriffsfehler beim verlassen dieser 
  ; Funktion. Durch Tests weiß ich jedoch, dass diese Fehlermeldungen an 
  ; sich nichts zu sagen haben. Deswegen wird das Fehlerhandling für die 
  ; Dauer dieser Funktionsausführung übersprungen...
  ; -----------------------------------------
  ; WICHTIG:
  ; Keine Ahnung warum, aber beim direkten Zugriff über die LinkedList meldet
  ; der Compiler Speicherzugriffsfehler. Indirekt über einen Zeiger kommt nichts!!!
  *record.SRecordSet = argv
  AddElement(ResultSet())
  *result.SRecordSet = @ResultSet()
  For i = 0 To argc-1
    If *record\Column[i] <> #Null
      *result\Record[i] = PeekS(*record\Column[i])
      Debug "Spalte: " + Str(i) + " Wert: " + PeekS(*record\Column[i])
    Else
      Debug "Spalte: " + Str(i) + " Wert: "
      *result\Record[i] = ""
    EndIf
  Next i
  ProcedureReturn 0
EndProcedure
Also nur zur Erläuterung, ich wollte extra keine extra LIB verwenden. Deshalb der Workaround unter PB, damit man die Dll zur Laufzeit austauschen kann.
Das komische daran ist, dass der Zugriffsfehler nie zu einer bestimmten Zeit kommt (selbst immer mit dem selben Result).

Könnte das was damit zu tun haben? Wenn nicht, einfach ignorieren :)

Grüße
Gesperrt