Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi wieder mal die Zeiger (https://www.delphipraxis.net/38924-wieder-mal-die-zeiger.html)

kiar 26. Jan 2005 08:45


wieder mal die Zeiger
 
hallo,

habe folgenden Record:
Delphi-Quellcode:
type
   TSettings = record
     FZa1 : String;
     FZa2 : String;
     iFk : Integer;
     iCo : Integer;
   end;
type PSettings = ^TSettings;
und den Zeiger, auf diesen Record.

mit der folgenden Routine versuche ich den Record mit Daten aus einer Inidatei zu füllen
Delphi-Quellcode:
procedure LoadSettings;
var
  Ini: TIniFile;
  xP : PSettings;
begin
    GetMem(xP, sizeOf(TSettings));
    Ini:= TIniFile.Create(ExtractFilePath(Paramstr(0)) + 'maxes.ini');
    with Ini do
      Begin
        with xP^ do
          begin
             FZa1:= ini.ReadString('Zahlen', 'Zahl1', '10');
             FZa2:= ini.ReadString('Zahlen', 'Zahl2', '10');
             iFk := ini.ReadInteger('Funktionen', 'Funktion', 0);
          end;
      end;
   ini.free;
end;
Leider bringt mir der Aufruf , immer eine Zugriffsverletzung.

Die Frage ist nun, was ist falsch an dieser Geschichte?

Danke Raik

edit : Die Schutzverletzung kommt beim Zugriff auf FZa2.

Sharky 26. Jan 2005 09:05

Re: wieder mal die Zeiger
 
Hai kiar,

scheint wohl am Typ String liegen. Wenn Du z.B. ShortString verwendest geht es. Frage mich aber nicht warum :roll:

Shaman 26. Jan 2005 09:07

Re: wieder mal die Zeiger
 
Hoi

Probier mal New anstatt GetMem.

Gruss
Shaman

st-matze 26. Jan 2005 09:09

Re: wieder mal die Zeiger
 
für dynamische strings werden nur 4byte oder so reserviert

versuchs mal so

Delphi-Quellcode:
 type
   TSettings = record
     FZa1 : String[100]; //kann natürlich auch ne andere zahl ausser 100 sein
     FZa2 : String[100];
     iFk : Integer;
     iCo : Integer;
   end;

kiar 26. Jan 2005 09:21

Re: wieder mal die Zeiger
 
hallo,

Habe ich schon gemacht und es klappt, leider ist der Zugriff von einer anderen Form auch nicht befriedigend.

wenn ich jetzt
Delphi-Quellcode:
var
  a:integer;
  xp:Psettings;
begin
     
    LoadSettings;
    Edit1.Text :=xp^.FZa1;
    Edit2.Text :=xp^.FZa2;
der Pointer stimmt, einmal in LoadSettings und in oben aufgeführter Procedure. Leider sind die Werte in FZa1 und Fza2 nicht nachvollziehbar und schwirren in den Weiten meines Rechners herum.


raik

Motzi 26. Jan 2005 09:52

Re: wieder mal die Zeiger
 
Das Problem ist wie bereits angesprochen der String bzw. das interne String-Handling. GetMem initialisiert den reservierten Speicher nicht, d.h. es können irgendwelche zufälligen Daten drinnenstehen und die String-Felder enthalten daher willkürliche Adressen. Weißt du einem dieser Strings nun einen neuen Inhalt zu, so versucht das interne String-Handling den Referenzzähler des "alten" Strings zu dekrementieren, da aber der String ja nicht wirklich auf einen String zeigt sondern eben nur eine willkürliche Adresse enthält endet das in einer Zugriffsverletzung.

Lösungen:
1) New verwenden (Compiler-Magic nimmt alle nötigen Initialisierungen vor)
2) AllocMem verwenden (ruft GetMem auf und initialisiert den Speicher anschließend mit FillChar)
3) selber den Speicher mit ZeroMemory oder FillChar initialisieren
4) die procedure Initialize verwenden...

kiar 26. Jan 2005 10:16

Re: wieder mal die Zeiger
 
hallo,

mit diesem Quelltext:
Delphi-Quellcode:
procedure LoadSettings;
var
  Ini: TIniFile;
  xP : PSettings;
begin
    new(xP);
    Ini:= TIniFile.Create(ExtractFilePath(Paramstr(0)) + 'maxes.ini');
    with Ini, xP^ do
      Begin
             FZa1:= ReadString('Zahlen', 'Zahl1', '10');
             FZa2:= ReadString('Zahlen', 'Zahl2', '10');
             iFk := ReadInteger('Funktionen', 'Funktion', 0);
      end;
   ini.free;
end;
trten erstmal kein Zugriffsverletzungen auf, leider ist der Zugriff auf die procedure von einen anderen form immer noch nicht definiert :pale:


erstmal Danke an Alle

Sharky 26. Jan 2005 10:27

Re: wieder mal die Zeiger
 
Zitat:

Zitat von kiar
... leider ist der Zugriff auf die procedure von einen anderen form immer noch nicht definiert ...

Hast Du die Funktionsdeklaration auch im Interface Teil deiner Unit eingetragen?

kiar 26. Jan 2005 10:41

Re: wieder mal die Zeiger
 
hallo Sharky,

ich sehe ja den Zeiger, die Adresse ist in beiden Fällen die gleiche.

zb: wird in FZa1 = '10' geschrieben.

der Aufruf aus der anderen Form, zeigt mir aber, nur Datenmüll an?

raik

Kedariodakon 26. Jan 2005 10:54

Re: wieder mal die Zeiger
 
Warum nimmst du überhaupt ein Record?
für was gibts Objecte?

Beispiel:

Delphi-Quellcode:
Unit Unit1;


Interface


Uses   SysUtils, IniFiles;


Type
   TSettings_Base = Class
   Private
      { Private-Deklarationen }
      FiCo: Integer;
    FiFk: Integer;
    FFZa1: String;
      FFZa2: String;
   Public
      { Public-Deklarationen }
      Function   Load:   Boolean;   Virtual;   Abstract;
      Property   FZa1:   String   Read FFZa1;
      Property   FZa2:   String   Read FFZa2;
      Property   iFk:   Integer   Read FiFk;
      Property   iCo:   Integer   Read FiCo;
   End;

   TSettings_Ini   = Class( TSettings_Base )
   Public
      { Public-Deklarationen }
      Function   LoadSettings:   Boolean;
   End;


Implementation



Function TSettings_Ini.LoadSettings:   Boolean;
Var   InI:   TIniFile;
Begin
   Result   := False;
   InI         := Nil;
   Try
      Try
         Ini         := TIniFile.Create( ExtractFilePath( Paramstr( 0 ) ) + 'maxes.ini' );
         FFZa1      := InI.ReadString(   'Zahlen',         'Zahl1',         '10'   );
         FFZa2      := InI.ReadString(   'Zahlen',         'Zahl2',         '10'   );
         FiFk      := InI.ReadInteger(   'Funktionen',   'Funktion1',   0         );
         FiCo      := InI.ReadInteger(   'Funktionen',   'Funktion2',   0         );
         Result   := True;
      Finally
         If Assigned( InI ) Then FreeAndNil( InI );
      End;
   Except
      On Error: Exception Do Begin
         Error.Message   := 'LoadSettings - Error:'#13#10 + Error.Message;
         Raise;
      End;
   End;
End;



End.
So in der Art würd ich das machen...


:dancer2: Es lebe die Objectorientiertheit :zwinker:

Bye


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:13 Uhr.
Seite 1 von 2  1 2      

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