Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Pointer auf Record - Strings problematisch ? (https://www.delphipraxis.net/141339-pointer-auf-record-strings-problematisch.html)

moelski 7. Okt 2009 10:00


Pointer auf Record - Strings problematisch ?
 
Moin !

Habe da eine Struktur:
Delphi-Quellcode:
type
  PClient  = ^TClient;
  TClient  = record
    PeerIP       : string[15];           { Cleint IP address }
    HostName     : String[40];           { Hostname }
    Connected    : TDateTime;            { Time of connect }
    RestString   : String;  
  end;
Diese Struktur verwende ich bei einem TCP Server um Infos über die Clients abzulegen:
Delphi-Quellcode:
procedure TMainFormServer.TCPServerConnect(AContext: TIdContext);
var NewClient: PClient;
begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.PeerIP     := AContext.Connection.Socket.Binding.PeerIP;
  NewClient.Connected  := Now;
  NewClient.RestString := '';

  AContext.Data        := TObject(NewClient);
end;
Wenn sich der erste Client connected klappt das ganz gut. Kommt aber ein zweite Client, dann erhalte ich einen Fehler:
Zitat:

Zugriffsverletzung bei Adresse 004051C0 in Modul 'XYZ.exe'. Lesen von Adresse 30345F4C.
Das Problem liegt hier:
NewClient.RestString := '';

Gibt es da generelle Probleme wenn ich in dem Record Strings ohne Längenangabe verwende?
Wird nicht für jeden String auch die Länge mitgespeichert? Dann sollte das doch kein Problem sein !?

mkinzler 7. Okt 2009 10:04

Re: Pointer auf Record - Strings problematisch ?
 
Zitat:

Gibt es da generelle Probleme wenn ich in dem Record Strings ohne Längenangabe verwende?
Ja. Denn das Feld ist dann nur ein Zeiger.

moelski 7. Okt 2009 10:08

Re: Pointer auf Record - Strings problematisch ?
 
Ah ok. Danke fpr die Info !

Wie kann ich denn dann einen String unbekannter Länge dort ablegen?

littleDave 7. Okt 2009 10:24

Re: Pointer auf Record - Strings problematisch ?
 
Versuch mal statt "GetMem" "New" zu benutzen

Delphi-Quellcode:
procedure TMainFormServer.TCPServerConnect(AContext: TIdContext);
var NewClient: PClient;
begin
  New(NewClient); // <-----

  NewClient.PeerIP     := AContext.Connection.Socket.Binding.PeerIP;
  NewClient.Connected  := Now;
  NewClient.RestString := '';

  AContext.Data        := TObject(NewClient);
end;

moelski 7. Okt 2009 10:37

Re: Pointer auf Record - Strings problematisch ?
 
Ja das sieht besser aus.
Aber was ist nun der Unterschied?

himitsu 7. Okt 2009 10:44

Re: Pointer auf Record - Strings problematisch ?
 
New entspricht
Delphi-Quellcode:
GetMem(NewClient, SizeOf(TClient));
Initialize(NewClient {, TClient}); // Strings, dynamische Arrays und Intefaces initialisieren

// bzw.

GetMem(NewClient, SizeOf(TClient));
ZeroMemory(NewClient, SizeOf(TClient));
Grund:
der String ist ein initialisierungspflichtiger Typ, da dessen Speicher von Delphi verwaltet wird
und ein "Leerstring" nunmal NIL ist.

ist der String jetzt nicht NIL und di versuchst diesem einen neuen Wert zuzuweisen, dann versucht Delphi den alten angeblich darin gespeicherten String freizugeben und dann knallt es natürlich.

[add]
PS: Dispose ist dann natürlich
Delphi-Quellcode:
Finalize(NewClient {, TClient}); // Strings, dynamische Arrays und Intefaces freigeben
FreeMem(NewClient);


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:05 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