Autor |
Beitrag |
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 22.11.07 15:37
Hi, ich hab hier einen (für mich seltsamen) Fehler:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TSystemProcs.FillCheckListBox(Box: TCheckListBox; Fill: String; Delimiter: String); var DummyArray: TStrArray; A: integer; begin DummyArray:=SystemProcs.DivideString(Fill,Delimiter); Box.Items.Clear;
for A:= 0 to High(DummyArray) do Box.Items.Add(DummyArray[A]);
for A:= 0 to Box.Items.Count-1 do Box.Checked[A]:=True;
Box.Sorted:=True; Box.Sorted:=False;
end; |
nach der markierten Zeile ist Box beschädigt (nach Box.Free kommt eine Access Violation). Aber nur, wenn ich Box als Parameter übergebe, sonst funktioniert es einwandfrei. Wo liegt mein Fehler? Habe noch nie Klassen so als Parameter übergeben.
Xion
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
gispos
      
Beiträge: 94
WIN 7
XE10, D2007
|
Verfasst: Fr 23.11.07 00:27
Erstellst Du die CheckListBox zur Laufzeit? Dann musst Du ihr ein Parent zuweisen.
Und wenn nicht, warum willst Du Sie wieder frei geben? Macht doch die Application.
Nach Box.Clear sollte Box.Items.BeginUpdate folgen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure FillCheckListBox(Box: TCheckListBox); var A: integer; begin Box.Clear; Box.Items.BeginUpdate; Try for A:= 0 to 9 do begin Box.Items.Add(IntToStr(A)+ ' Alles OK'); Box.Checked[A]:=True; end; Box.Sorted:=True; finally Box.Items.EndUpdate; Box.Sorted:=False; end; end; |
Also dass Du Sie alls Parameter übergeben tust, hatt keinerlei Auswirkung.
Obiger Code läuft reibungslos.
Gruß gispos
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 10:43
Hi,
ja ich erstelle die Box zur Laufzeit und sie hat auch ein Parent. Mein Programm ist eigentlich fertig und läuft einwandfrei, nur beschädigt die Funktion mir irgendwie meine Box. Und ich will sie selbst zerstören, weil ich sie nicht mehr brauche. Und unsichtbares Zeugs da rumliegen lassen ist doch ziemlich unsauber, vor allem glaube ich nicht, dass die Application die Box "Free"en kann, wenn sie beschädigt ist.
Ich denke mal, es liegt an der Übergabe der Klasse. Da es ein Pointer ist, ist dieser vermutlich nach dem Sortieren nicht mehr gültig (da vermutlich in einen anderen Speicherbereich geschrieben wird). Aber wie ich das verhindern kann, keine Ahnung  Ich müsste irgendwie an den neuen Pointer kommen.
Xion
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 24.11.07 11:33
Ich kann in dem kleinen Source zu mindest keinen Fehler erkennen. Der Fehler liegt wohl an einer anderen Stelle.
Vielleicht solltest du einen kompletten Code schicken, der den Fehler zum Vorschein bringt.
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 11:41
Der komplette Code ist vielleicht etwas viel
Es muss aber hier sein, weil vor dem Sorted:=True geht Box.Free, danach nicht mehr. Und wenn ich die Sorted ausklammer gehts auch einwandfrei...ich brauch das Sorted auch gar nicht hab ich gesehen, mit wärs mir aber trotzdem lieber.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 24.11.07 11:50
Nicht *den* kompletten Code sondern einen für uns möglichst direkt ausführbaren, möglichst kleinen Code, der aber den Fehler gerade noch erzeugt. Sonst kann ich dir schwer helfen, da ich keinen Fehler im Code oben sehe. Wenn ich den Code oben mit einer TCheckListBox füttere gibt's bei mir keine Exceptions.
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 12:08
ach, klar, stimmt
hmm, komisch...es muss wohl irgendwie mit der BDE zusammenhängen, nur die procedure läuft bei mir auch...komisch
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 12:34
ich kriegs nicht hin...wenn ich im Prog irgendwas ausklammere, dann läufts, aber in dem, was ich ausklammer, ist der Fehler nicht drin...weil wenn ich was andres ausklammere, dann läufts auch...sehr komisch...was hat das mit der "Zufalls-Exception" eigentlich auf sich?
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 24.11.07 12:46
Die Wahrscheinlichkeit, dass es an der VCL liegt, ist wohl viel kleiner als, dass du einen Bug in deinem Code hast. Aber wie gesagt, wenn wir den Fehler nicht reproduzieren können wird's schwer dir zu helfen.
- Wie sieht die Access Violation aus? Auf welche Adresse kann nicht zugegriffen werden? Irgend eine "Zufällige", oder eine in der Nähe von 0?
- Du kannst auch mal versuchen "[x] Use debug DCUs" bei den Compiler-Einstellungen einzuschalten und schrittweise den VCL-Source durchzugehen.
- Den Call-Stack an der Exception-Stelle könntest du uns auch mal posten.
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 12:57
Die Debug-DCUs spucken folgendes aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| class function TObject.InheritsFrom(AClass: TClass): Boolean; {$IFDEF PUREPASCAL} var ClassPtr: TClass; begin ClassPtr := Self; while (ClassPtr <> nil) and (ClassPtr <> AClass) do ClassPtr := PPointer(Integer(ClassPtr) + vmtParent)^; Result := ClassPtr = AClass; end; {$ELSE} asm JMP @@haveVMT @@loop: MOV EAX,[EAX] @@haveVMT: CMP EAX,EDX JE @@success MOV EAX,[EAX].vmtParent TEST EAX,EAX JNE @@loop JMP @@exit @@success: MOV AL,1 @@exit: end; {$ENDIF} |
Hier die Violations...
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 24.11.07 13:12
Hast du alle Variablen initialisiert, keine Speicherbereiche unabsichtlich überschrieben, stets try-finally-Blöcke verwendet und die Box mit FreeAndNil statt mit .Free freigegeben? Keine Compiler-Warnungen ignoriert? Sind während der Ausführung sonstige Exceptions aufgetreten?
Bei der zweiten Fehlermeldung war ganz offensichtlich eine Objektreferenz nil ($A ist dabei der Offset zum Feld, worauf zugegriffen werden sollte).
Bitte noch den Call-Stack, da InheritsFrom von ziemlich überall aufgerufen werden kann. 
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Sa 24.11.07 13:44
delfiphan hat folgendes geschrieben: | Hast du alle Variablen initialisiert |
denk ich doch
delfiphan hat folgendes geschrieben: | keine Speicherbereiche unabsichtlich überschrieben |
gute Frage
delfiphan hat folgendes geschrieben: | stets try-finally-Blöcke verwendet |
wenn nötig (nicht stets)
delfiphan hat folgendes geschrieben: | die Box mit FreeAndNil statt mit .Free freigegeben |
Box.Free;
Box:=nil;
delfiphan hat folgendes geschrieben: | Keine Compiler-Warnungen ignoriert |
nö
delfiphan hat folgendes geschrieben: | Sind während der Ausführung sonstige Exceptions aufgetreten? |
nein
delfiphan hat folgendes geschrieben: | Bitte noch den Call-Stack |
Wo kireg ich den her?
delfiphan hat folgendes geschrieben: | da InheritsFrom von ziemlich überall aufgerufen werden kann. |
von Box.Free, weil da ja der Fehler kommt. Ich hab mal den Status von AblBox angehängt, den es zum Zeitpunkt des Frees hat
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 25.11.07 16:45
Delphi-Quelltext ist nicht äquivalent zu
Delphi-Quelltext
Die erste Variante ist etwas schwächer. Eher sowas wie FreeAndMaybeNil  . Bei der ersten Variante ist Box nach Free nämlich nicht nil, wenn im Destruktor eine Exception geraised wurde.
Call Stack: Wenn du das Programm aus der IDE startest klickst du bei der Exception auf "Break". Danach View > Debug Windows > Call Stack.
Bei wirklich sicher geschriebenem Code sieht man eigentlich nie Access Violations, und wenn, dann eher Nullpointer-Exceptions.
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 26.11.07 21:02
Also hier der Aufruf-Stack...
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 26.11.07 22:47
Könntest du die Stackframes noch einschalten (Compiler-Optionen) und mit den DCUs nochmals den Callstack fotographieren ;D
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 29.11.07 15:15
ich hab irgendwie das dumme Gefühl, ich stell mich blöd an 
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Do 29.11.07 20:50
Im CallStack ist auch nichts besonderes zu sehen. Es ist jedoch merkwürdig, wenn du sagst, dass die Exception in Box.Free auftaucht. Denn laut CallStack ist kein Free zu sehen sondern er wollte gerade die CheckListBox neu zeichnen. Dabei fragt er die erste Zeile ab, ob es ein Header ist. Aber die Meta-Daten der ersten Zeile scheinen Korrupt zu sein...
Leider hat's für die Aufklärung des Problems nicht gereicht 
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Fr 30.11.07 14:57
naja, ich muss sagen, das Problem ist nicht so groß. Da ich sowieso sortierte Daten reinpacke ist das nicht so schlimm, wenn er nicht sortieren kann.
Danke für dein Durchhaltevermögen
also erstmal ist das Topic auf Eis gelegt 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
|