Autor |
Beitrag |
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 17.07.07 14:18
Hallo
Ich hab' da ein Problem
Mein Code sieht (gekürzt) so aus: 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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| ...
type TFIniValue = record ... end;
TFIniSection = record ... Values: array of TFIniValue; ValuesLength: Cardinal; ... end;
TFIniFile = class private Sections: array of TFIniSection; SectionsLength: Cardinal; ... CurrentSection: Integer; ... public constructor Create(FileName: String); ... end;
...
implementation
constructor TFIniFile.Create(FileName: String); var Buf, Buf1, Buf2: String; begin ... SetLength(Sections, SectionsLength+1); inc(SectionsLength); ... CurrentSection := SectionsLength-1; ... with Sections[CurrentSection] do begin SetLength(Values, ValuesLength+1); inc(ValuesLength); ... end; ... end;
... |
Nun bekomme ich in der markierten Zeile eine AV: Access violation at adress 0045B13A in module 'test.exe'. Read of address 00000008
Was hab' ich falsch gemacht?
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 17.07.07 21:14
Du hast grad genau die Zeilen rausgelassen, die für die Fehlerdiagnose interessant gewesen wären. Poste mal bitte den Gesamten Constructor.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 17.07.07 21:52
SetLength löst keine AccessViolation aus. Ist die Instanz von Sections gültig?
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mi 18.07.07 15:20
Hier mal der Komplette Constructor inkl. den zwei Funktionen, die er noch verwendet: 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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| constructor TFIniFile.Create(FileName: String); var Buf, Buf1, Buf2: String; begin AssignFile(IniFile, FileName); Reset(IniFile); while not EOF(IniFile) do begin readln(IniFile, Buf); DeleteSpaces(Buf); if (Pos('[', Buf) <> -1 ) and (Buf[Length(Buf)-1] = ']') then begin SetLength(Sections, SectionsLength+1); inc(SectionsLength); Sections[SectionsLength-1].Deleted := false; Sections[SectionsLength-1].Name := Copy(Buf, 1, Length(Buf)-3); CurrentSection := SectionsLength-1; end else begin if Pos('=', Buf) = -1 then continue; SplitAt(Buf, Buf1, Buf2, '='); DeleteSpaces(Buf1); DeleteSpaces(Buf2); with Sections[CurrentSection] do begin SetLength(Values, ValuesLength+1); inc(ValuesLength); Values[ValuesLength-1].Name := Buf1; Values[ValuesLength-1].Value := Buf2; Values[ValuesLength-1].Deleted := false; end; end; end; CurrentSection := -1; end;
procedure SplitAt(const Str: String; var Sub1, Sub2: String; const Chr: Char); var ChrPos: Integer; begin ChrPos := Pos(Chr, Str); if ChrPos = -1 then begin Sub1 := Str; Sub2 := ''; end else begin Sub1 := Copy(Str, 0, ChrPos-1); Sub2 := Copy(Str, ChrPos+1, Length(Str)-ChrPos); end; end;
procedure DeleteSpaces(var Str: String); var LStrPos, i: Cardinal; LastNSpc, FirstNSpc: Integer; begin if (Pos(' ', Str) = -1) or (Length(Str) = 0) then exit; LStrPos := Length(Str)-1; FirstNSpc := -1; for i := 0 to LStrPos do begin if Str[i] <> ' ' then begin FirstNSpc := i; break; end; end; LastNSpc := -1; for i := LStrPos downto 0 do if Str[i] <> ' ' then begin LastNSpc := i; break; end; Str := Copy(Str, FirstNSpc, LastNSpc-FirstNSpc+1); end; | Zum leichteren verständnis: Create liest eine Zeile aus einer Ini-Datei entweder in einen Sektionen- oder einen Wertepuffer ein; SplitAt teilt einen String an einem Char (der dabei wegfällt) und DeleteSpaces löscht Leerzeichen, die am Anfang und am Ende eines Strings stehen.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 18.07.07 15:26
Wo wird Sectionslength und ValuesLength initialisiert? Schalte mal deine Compilerwarnungen EIN! Dann siehst Du solche Schusseligkeitsfehler schneller.
_________________ Na denn, dann. Bis dann, denn.
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mi 18.07.07 15:35
Ich hab's mal mit Initialisierung versucht, die einzige Veränderung ist, dass die AV jetzt Read of Address FFFFFFF8 heißt. Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| constructor TFIniFile.Create(FileName: String); var Buf, Buf1, Buf2: String; begin AssignFile(IniFile, FileName); Reset(IniFile); SectionsLength := 0; CurrentSection := -1; while not EOF(IniFile) do begin ... inc(SectionsLength); Sections[SectionsLength-1].ValuesLength := 0; Sections[SectionsLength-1].Deleted := false; Sections[SectionsLength-1].Name := Copy(Buf, 1, Length(Buf)-3); ... end; CurrentSection := -1; end; | Meine Compilerwarnungen waren eingeschaltet, eine Meldung (außer der Erfolgsmeldung) hab ich nicht bekommen.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 18.07.07 15:52
_________________ Na denn, dann. Bis dann, denn.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 18.07.07 19:53
Silas hat folgendes geschrieben: | Hier mal der Komplette Constructor inkl. den zwei Funktionen, die er noch verwendet:
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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| constructor TFIniFile.Create(FileName: String); var Buf, Buf1, Buf2: String; begin AssignFile(IniFile, FileName); Reset(IniFile); SectionsLength := 0; while not EOF(IniFile) do begin readln(IniFile, Buf); Buf := Trim(Buf); if (Pos('[', Buf) <> -1 ) and (Buf[Length(Buf)-1] = ']') then begin SetLength(Sections, SectionsLength+1); inc(SectionsLength); Sections[SectionsLength-1].Deleted := false; Sections[SectionsLength-1].Name := Copy(Buf, 1, Length(Buf)-3); CurrentSection := SectionsLength-1; Sections[CurrentSection] := TINISection.Create(Self); ValuesLength := 0; end else begin if Pos('=', Buf) = -1 then continue; SplitAt(Buf, Buf1, Buf2, '='); Buf1 := Trim(Buf1); Buf2 := Trim(Buf2); with Sections[CurrentSection] do begin SetLength(Values, ValuesLength+1); inc(ValuesLength); Values[ValuesLength-1] := TINIValue.Create; Values[ValuesLength-1].Name := Buf1; Values[ValuesLength-1].Value := Buf2; Values[ValuesLength-1].Deleted := false; end; end; end; CurrentSection := -1; end;
procedure SplitAt(const Str: String; var Sub1, Sub2: String; const Chr: Char); var ChrPos: Integer; begin ChrPos := Pos(Chr, Str); if ChrPos = -1 then begin Sub1 := Str; Sub2 := ''; end else begin Sub1 := Copy(Str, 0, ChrPos-1); Sub2 := Copy(Str, ChrPos+1, Length(Str)-ChrPos); end; end;
procedure DeleteSpaces(var Str: String); var LStrPos, i: Cardinal; LastNSpc, FirstNSpc: Integer; begin if (Pos(' ', Str) = -1) or (Length(Str) = 0) then exit; LStrPos := Length(Str)-1; FirstNSpc := -1; for i := 0 to LStrPos do begin if Str[i] <> ' ' then begin FirstNSpc := i; break; end; end; LastNSpc := -1; for i := LStrPos downto 0 do if Str[i] <> ' ' then begin LastNSpc := i; break; end; Str := Copy(Str, FirstNSpc, LastNSpc-FirstNSpc+1); end; |
Zum leichteren verständnis: Create liest eine Zeile aus einer Ini-Datei entweder in einen Sektionen- oder einen Wertepuffer ein; SplitAt teilt einen String an einem Char (der dabei wegfällt) und DeleteSpaces löscht Leerzeichen, die am Anfang und am Ende eines Strings stehen. |
Hab mal ein wenig rumgebastelt ... im Kopf ... Sollte so funzen ... Ggf. die Aufrufe der Konstruktoren mal anpassen 
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Do 19.07.07 10:51
... und wenn der else-Teil zuerst angesprungen wird, passiert das Gleiche (weil 'CurrentSection' undefiniert ist).
_________________ Na denn, dann. Bis dann, denn.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 19.07.07 12:45
So viel Denken trau ich ihm zu, dass er die dafür benötigte Denkleistung alleine aufbringt ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Do 19.07.07 15:39
Danke Dir, BenBE! Funzt jetzt wunderbar. 
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
|