Autor Beitrag
Silas
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Di 17.07.07 14:18 
Hallo :wave:

Ich hab' da ein Problem :)

Mein Code sieht (gekürzt) so aus:
ausblenden volle Höhe 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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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



BeitragVerfasst: Di 17.07.07 21:52 
SetLength löst keine AccessViolation aus. Ist die Instanz von Sections gültig?
Silas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Mi 18.07.07 15:20 
Hier mal der Komplette Constructor inkl. den zwei Funktionen, die er noch verwendet:
ausblenden volle Höhe 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:
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: Stringvar Sub1, Sub2: Stringconst 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) = -1or (Length(Str) = 0then 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 18.07.07 15:52 
user profile iconSilas hat folgendes geschrieben:
Ich hab's mal mit Initialisierung versucht, die einzige Veränderung ist, dass die AV jetzt Read of Address FFFFFFF8 heißt.

Ein Indiz dafür, das das auch gefehlt hat... Und zwar initialisierst Du 'CurrentSection' auf -1.. Wenn nun CurrentSection vorher nicht gesetzt wird, dann geht dieser Aufruf in die Pampa ('FFFFFF8') vorher war CurrentSection mangels Initialisierung bei 0 (schätze ich) und dann könnte das passen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
...
  with Sections[CurrentSection] do begin
     SetLength(Values, ValuesLength+1);
 ...

_________________
Na denn, dann. Bis dann, denn.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 18.07.07 19:53 
user profile iconSilas hat folgendes geschrieben:
Hier mal der Komplette Constructor inkl. den zwei Funktionen, die er noch verwendet:
ausblenden volle Höhe 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:
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: Stringvar Sub1, Sub2: Stringconst 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) = -1or (Length(Str) = 0then 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 :P

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: 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 ;-)