Ergebnis 1 bis 4 von 4

Thema: [Delphi] TIniFile und EAccessViolation

  1. #1

    [Delphi] TIniFile und EAccessViolation

    Diesmal habe ich, denke ich, wirklich ein Problem, auf das ich mir keinen Reim machen kann.

    Ich habe ein dynamisches Array "VolkDaten" dessen Inhalt ich in ein IniFile schreiben will. Das Array wird vorher dimensioniert und auch gefüllt.
    Hier mal der Code der Funktion zum Schreiben in das IniFile:

    Code:
    procedure TPeople.ResetIniDataVolk;
    var Ini: TIniFile;
        i: integer;
        Datei: Textfile;
        b: TGroupBuilding;
        u: TGroupUnit;
        Test:string;
    begin
      ResetVolkData;
      AssignFile(Datei, GamePath+'daten\volk.ini');
     try
      ReWrite(datei);
      CloseFile(datei);
    // Ini-Datei beschreiben:
       Ini:=TIniFile.Create(GamePath+'daten\volk.ini');
       Ini.WriteInteger('Allgemein', 'Anzahl', 4);
      for i:=0 to 3 do
      begin
       with VolkDaten[i] do
       begin
        Ini.WriteString('Allgemein', 'Volk'+InttoStr(i), Name);
         for b:=Farm to Military do
          [b]Ini.WriteInteger(Name, 'BuildingHP'+TGrBuildtoStr(b), BuildingHP);
         for u:=Regular to Artilery do
          begin
           Ini.WriteInteger(FVolkDaten[i].Name, 'UnitHP'+TGrUtoStr(u), FVolkDaten[i].UnitHP[u]);
           Ini.WriteInteger(FVolkDaten[i].Name, 'UnitAttack'+TGrUtoStr(u), FVolkDaten[i].UnitAttack[u]);
           Ini.WriteInteger(FVolkDaten[i].Name  , 'UnitDefense'+TGrUtoStr(u), FVolkDaten[i].UnitDefense[u]);
          end;
       end;
      end;
     finally
      Ini.Free;
     end;
    end;
    An der fett markierten Zeile bricht das Programm dann mit einer EAccessViolation ab. Das interessante und für mich seltsame, an der Geschichte ist, daß ich vorher eine Funktion hatte, die das Array korrekt in ein IniFile geschrieben hat. Die einzigen Änderung die ich vorgenommen habe um zu obiger Prozedur zu kommen waren:
    - Das Array als Property der Klasse TPeople eingeführt und die Prozedur zu einer Methode selbiger Klasse gemacht.
    - Einige Schleifen eingeführt
    Wenn ich obigen Code als eigenständige Prozedur aufrufe und Volkdaten[i] über das Objekt People aufrufe, kommt derselbe Fehler. Selbst wenn ich Name oder BuildingHP(b) durch konstante Werte ersetze kommt der Fehler, ebenso wenn ich die Schleife entferne und b durch einen festen Wert ersetze.
    Die ersten beiden WriteBefehle werden ausgeführt, allerdings taucht der Wert von
    Code:
    Ini.WriteString('Allgemein', 'Volk'+InttoStr(i), Name);
    Nicht im IniFile auf.. wenn ich Name durch einen konstanten String ersetze allerdings schon. Aber wie gesagt, wenn ich in der abbrechende Zeile gar nicht mehr auf VolkDaten[i] zugreife taucht der Fehler trotzdem auf.
    Ich hab ehrlich gesagt keine Ideen mehr wo der Fehler seine Ursache haben könnte, geschweige denn wie er zu beheben ist.
    Falls ihr noch weitere Codeschnipsel braucht, einfach sagen.
    ResetVolkData funktioniert übrigens tadellos.

  2. #2
    Was sind denn das fuer Datentypen ?
    b: TGroupBuilding;
    u: TGroupUnit;

  3. #3
    Selbst erstellte Aufzählungstypen.
    Edit:
    Code:
    TGroupBuilding = (Farm, Mine, Production, House, Special, Military);
    TGroupUnit = (Regular, Horse, Shoot, Mage, Artilery);
    Edit2:
    Der Fehler lag anscheindend doch in der Procedure ResetVolkData.
    Damit der Thread hier nicht total sinnlos ist, frag ich einfach mal wieso ich innerhalb von ResetVolkData nicht auf die Eigenschaft VolkDaten zurückgreifen sondern auf das Feld FVolkDaten zurückgreifen muss (seit der Änderung wird das IniFile auch korrekt beschrieben).
    Hier mal die Typdeklaration von TPeople:
    Code:
    TPeople = class
          private
           FProgramPath: string;
           FVolkDaten: array of TVolkDaten;
           procedure SetVolkDaten(idx: integer; value: TVolkDaten);
           function GetVolkDaten(idx:integer):TVolkDaten;
          public
           constructor Create;
           procedure ResetIniDataVolk;
           procedure GetIniDataVolk;
           procedure ResetIniData;
           procedure ResetVolkData;
           property GamePath: string read FProgramPath write FProgramPath;
           property VolkDaten[idx:integer]: TVolkDaten read GetVolkDaten write SetVolkDaten;
          end;
    .
    .
    .
    
    procedure TPeople.SetVolkDaten(idx: integer; value: TVolkDaten);
    begin
    FVolkDaten[idx]:=value;
    end;
    In ResetVolkData habe ich FVolkDaten dimensioniert und dann mit
    Code:
    with VolkDaten[0] do
    Das ganze gefüllt. Als ich da das VolkDaten in FVolkDaten geändert habem hat sich der Fehler behoben. Wäre über ein wenig Aufklärung in Bezug darauf dankbar.. eigentlich habe ich gedacht ich hätte die Properties verstanden, aber das scheint nicht wirklich der Fall zu sein. =)

    Geändert von MagicMagor (17.06.2004 um 19:58 Uhr)

  4. #4
    Wieso solltest du denn in SetVolkDaten auf Volkdaten zugreifen wollen und nicht auf FVolkDaten ?

    Properties sind wenn man so will pseudovariblen. Fuer das lesen wird die Read-Funktion aufgerufen und fuer das Schreiben die Write-Funktion. Wenn du nun in der Funktion zum Schreiben in das Property wieder auf das Property zugreifst hast du doch sowas wie eine Endlosschlife, oder er macht dir irgend welchen undefinierten mist.

    Zudem sind zugriffe ueber properties in der regel wesentlich langsamer als auf variablen, da ja erst sprungaddressen etc generiert werden muessen usw usw ... Innerhalb des Objectes also nach moeglichkeit immer ueber das Member (also das F*) gehen und properties AUSSCHLIESSLICH als schnittstellen verwenden zum setzen von bestimmen eigenschaften, nicht zum exzessiven datenverkehr

    Falls ich jetzt was falsch verstanden haben sollte, und du was anderes machen wolltest, klaer mich bitte auf ^__^

    btw .. ich selber hab noch nie aufzaehlungen in Pascal verwendet ^__^

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •