![]() |
wieder mal die Zeiger
hallo,
habe folgenden Record:
Delphi-Quellcode:
und den Zeiger, auf diesen Record.
type
TSettings = record FZa1 : String; FZa2 : String; iFk : Integer; iCo : Integer; end; type PSettings = ^TSettings; mit der folgenden Routine versuche ich den Record mit Daten aus einer Inidatei zu füllen
Delphi-Quellcode:
Leider bringt mir der Aufruf , immer eine Zugriffsverletzung.
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; Die Frage ist nun, was ist falsch an dieser Geschichte? Danke Raik edit : Die Schutzverletzung kommt beim Zugriff auf FZa2. |
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: |
Re: wieder mal die Zeiger
Hoi
Probier mal New anstatt GetMem. Gruss Shaman |
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; |
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:
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.
var
a:integer; xp:Psettings; begin LoadSettings; Edit1.Text :=xp^.FZa1; Edit2.Text :=xp^.FZa2; raik |
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... |
Re: wieder mal die Zeiger
hallo,
mit diesem Quelltext:
Delphi-Quellcode:
trten erstmal kein Zugriffsverletzungen auf, leider ist der Zugriff auf die procedure von einen anderen form immer noch nicht definiert :pale:
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; erstmal Danke an Alle |
Re: wieder mal die Zeiger
Zitat:
|
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 |
Re: wieder mal die Zeiger
Warum nimmst du überhaupt ein Record?
für was gibts Objecte? Beispiel:
Delphi-Quellcode:
So in der Art würd ich das machen...
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. :dancer2: Es lebe die Objectorientiertheit :zwinker: Bye |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz