Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Access Violation bei setlength bei Int Array (https://www.delphipraxis.net/165083-access-violation-bei-setlength-bei-int-array.html)

PhilmacFLy 14. Dez 2011 12:20

Delphi-Version: 2005

Access Violation bei setlength bei Int Array
 
Ok ich hab folgendes Problem ich bekomme bei einem Integer Array eine AV bei folgendem Code:
Delphi-Quellcode:
procedure Tfrm_gui_doku_laden.btt_ladenClick(Sender: TObject);
var
idtrain, tmpid: Integer;
idcount, tmpcount:Integer;
i: integer;
versioncount: Integer;
version: Integer;
begin
//i := 0;
versioncount := 0;
version := 42;
idcount := 0;
gesamt := 0;
versionen := 0;
//ShellExecute(Application.Handle,'open',PChar(ExtractFilePath(ParamStr(0)) +'Zeigtrai.exe'), Nil, Nil, SW_SHOW);
zConnection1.Connected := true;
    with ZReadonlyquery1 do
      begin
        SQL.TExt := 'Select ID_Training, Text from Training Where ID_Geraetenr = :ge and ID_KDNR = :kdnr' +
        ' and ID_such = :such and ID_Trainingsmodus = :mod Order By Version ASC';
        Params.ParamByName('ge').AsInteger := Geraetenummer;
        Params.ParamByName('kdnr').AsInteger := frm_gui_main.kunde.id;
        Params.ParamByName('such').AsInteger := idsuch;
        Params.ParamByName('mod').AsInteger := idmodus;
        Open;
        idtrain := FieldbyName('ID_Training').AsInteger; //Holt die ID der ersten Version eines Trainings
        Close;
        tmpid := idtrain;
        while version <> 0 do //Liest solang die Version aus bis keine neue Version kommt
          begin               //dient dem zweck das ich die größe des Arrays festlegen kann
                               //nach der Anzahl der Versionen und anzahl der Trainingswerte pro Version
            Sql.Text := 'Select Versionsaenderung From Training Where Id_Training = :id';
            Params.ParamByName('id').AsInteger := tmpid;
            Open;
            version := FieldbyName('Versionsaenderung').AsInteger;
            Close;
            inc(versioncount);
            SQL.TExt := 'Select Count(ID_Training) From Trainingswerte Where ID_Training = :id';
            Params.ParamByName('id').AsInteger := tmpid;
            Open;
            tmpcount := FieldbyName('Count').AsInteger;
            Close;
            if tmpcount > idcount then
              idcount := tmpcount;
            tmpid := version;
          end;
        setlength(wertarr, versioncount+1, idcount);
        if checkbox1.Checked then
          setlength(anzahlarr, versioncount+1); //<---- Hier (Checkbox is nur zum testen obs wirklich das ist)
        for i := 0 to versioncount+1 do
          anzahlarr[i] := 0;
        i := 0;
        versionen:=versioncount;
        tmpid := idtrain;
        versioncount := 0;
        version := 42;
        while version <> 0 do
          begin //Liest dann die Werte aus in das array
            Sql.Text := 'Select Versionsaenderung From Training Where Id_Training = :id';
            Params.ParamByName('id').AsInteger := tmpid;
            Open;
            version := FieldbyName('Versionsaenderung').AsInteger;
            Close;
            inc(versioncount);
            Sql.Text := 'Select * From Trainingswerte Where ID_Training = :id Order By Datum, Startzeit';
            Params.ParamByName('id').AsInteger := tmpid;
            Open;
            while not eof do
              begin
                wertarr[versioncount, i].Datum := FieldbyName('Datum').AsDateTime;
                wertarr[versioncount, i].Start := FieldbyName('Startzeit').AsDateTime;
                wertarr[versioncount, i].Stop := FieldbyName('Stopzeit').AsDateTime;
                wertarr[versioncount, i].Fehlerl := FieldbyName('Fehlerlinks').AsInteger;
                wertarr[versioncount, i].Fehlerr := FieldbyName('Fehlerrechts').AsInteger;
                wertarr[versioncount, i].startpos := FieldbyName('Startpos').AsInteger;
                wertarr[versioncount, i].stoppos := FieldbyName('Stoppos').AsInteger;
                next;
                inc(i);
              end;
            Close;
            anzahlarr[versioncount]:=i;
            gesamt:=gesamt+i;
            tmpid := version;
          end;
      end;
    Frm_ZeigTr:=TFrm_ZeigTr.Create(self);
    Frm_ZeigTr.ShowModal;
    zConnection1.Connected := false;
end;
Wenn die Checkbox nicht gecheked ist passiert nichts wenn sie gecheckt ist AV, aber auch nicht immer das ist das seltsame.

Hier noch ein paar Definitionen:
Delphi-Quellcode:
  public
    wertarr: Array of Array of TTrainwerte;
    anzahlarr: Array of Integer;
    versionen,gesamt: Integer;
  end;
und von TTrainwerte
Delphi-Quellcode:
  TTrainwerte=class
  public
  id: Integer;
  Datum: Tdate;
  startzeit: TTime;
  stopzeit: TTime;
  FehlerL: Integer;
  FehlerR: Integer;
  Startpos: Integer;
  Stoppos: Integer;
  Notiz: String;
  procedure getvalues(Query: TZquery); overload;
  procedure getvalues(Query: TZReadOnlyQuery); overload;
  procedure insertvalues(Query: TZquery); overload;
  procedure insertvalues(Query: TZReadOnlyquery); overload;
  destructor Destroy();
  end;
Wäre ehct glücklich wenn mir jemand helfen könnte.

himitsu 14. Dez 2011 13:05

AW: Access Violation bei setlength bei Int Array
 
Wenn du dort eine Zugriffsverletzung bekommst, dann hast du dir wo anders den Speicher zerschossen.

Bummi 14. Dez 2011 13:19

AW: Access Violation bei setlength bei Int Array
 
ich habe gerade keine Zeit, aber das sieht schon mal böse aus:

Delphi-Quellcode:
        if checkbox1.Checked then
          setlength(anzahlarr, versioncount+1);
        for i := 0 to versioncount+1 do
          anzahlarr[i] := 0;

himitsu 14. Dez 2011 13:56

AW: Access Violation bei setlength bei Int Array
 
Also doch den Speicher zerschossen/überschrieben. :stupid:

Projektoptionen > die Indexprüfung aktivieren

PhilmacFLy 14. Dez 2011 14:05

AW: Access Violation bei setlength bei Int Array
 
Zitat:

Zitat von himitsu (Beitrag 1141346)
Also doch den Speicher zerschossen/überschrieben. :stupid:

Projektoptionen > die Indexprüfung aktivieren

Kann das sein das es in D2k5 Bereichsüberprüfung heisst?

Edit: Was mir grad einfällt wenn ich ein setlenght auf versioncount+1 mach, dann is das array von 0 - versionscount definiert und nicht bis versionscount+1 ich test das mal

Edit2:
Ok jetzt krieg ich bei
Delphi-Quellcode:
for i := 0 to versioncount do
          anzahlarr[i] := 0;
Nen fehler bei Bereichsüberprüfung

xZise 14. Dez 2011 14:40

AW: Access Violation bei setlength bei Int Array
 
Ich würde das so machen:
Delphi-Quellcode:
for i := 0 to High(anzahlarr) do
Weil, wenn dort die Bereichsprüfung zuschlägt, dann greifst du da ja auf Elemente außerhalb des Arrays zu. Und da er die Arraylänge ja nicht immer ändert, sondern nur, wenn die eine Checkbox markiert ist, kann es ja sein, dass das Array kleiner ist, als „gedacht“.

Achso diese Änderung bewirkt natürlich „nur“, dass er nicht außerhalb des Arrays zugreift. Es könnte natürlich auch sein, dass das aber nie passieren soll. Dann würde meine Lösung nur das Symptom und nicht das Problem beheben.

Fabian

himitsu 14. Dez 2011 14:46

AW: Access Violation bei setlength bei Int Array
 
Bereichsprüfung müßte die Prüfung der Variablen (Integer/Float) sein. :gruebel:

*nachseh*

OK, die Bereichsprüfung ist das.
Überlaufprüfung ist das Andere.

PhilmacFLy 14. Dez 2011 14:54

AW: Access Violation bei setlength bei Int Array
 
Alles klar mit High(anzahlarr) hats funktinoiert, manchmal kanns so einfach sein

himitsu 14. Dez 2011 15:16

AW: Access Violation bei setlength bei Int Array
 
Zitat:

Zitat von PhilmacFLy (Beitrag 1141355)
Alles klar mit High(anzahlarr) hats funktinoiert,

High ist aber nicht "immer" die "wirkliche" Lösung ... nämlich wenn eigentlich mehr im Array sein sollte, dieses aber irgendwo diefalsche Größe bekahm.

Bummi 14. Dez 2011 17:12

AW: Access Violation bei setlength bei Int Array
 
@himitsu
ich denke doch, der Fehler liegt dann nämlich an einer anderen Stelle


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz