AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

(Keine) Freude mit Zeigern

Ein Thema von Dani · begonnen am 26. Dez 2003 · letzter Beitrag vom 26. Dez 2003
Antwort Antwort
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#1

(Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 03:59
Frohe Weihnachten allerseits

Ich arbeite gerade zum Spass an einem mittelmäßigen Chatprogramm für Delphi, was bisher auch relativ zügig voran ging, aber jetzt scheitert es an einem ziemlich nervigen (weil eigentlich nicht komplizierten) Problem....Zeiger....

Kann mir da evtl. jemand etwas unter die Arme greifen?

In der Haupt-Unit sind nämlich u.A. folgende Typen und Variablen definiert:

Delphi-Quellcode:
type

{TCchatMessage - Träger für alle Art von Datenpacketen, die zwischen Client und Server verschickt werden}
TChatMessage = record
    MsgType : Byte;
    MsgContent : array[0..1023] of char;
   end;

{TChatRoom - Ein Element innerhalb der Chatroomsm ObjectList}
  TChatroom = class(TObject)
    ClientsInRoom : TList;
    Name : String[30];
   end;

  PChatroom = ^TChatroom;

{TChatRoom - Virtuelle Entsprechung eines Chat-Benutzers und Element der AllClients ObejectList}
  TChatClient = class(TObject)
    Nickname : String[15];
    IPAddr : String[16];
    Room : PChatroom;
    Hash, awaymsg, dndmsg, abouttext : String;
    BannedFromRooms, IgnoredClients : TStrings;
    HasIdentified, IsAdmin: Boolean;
    Status : TClientstatus;
    Thread : PIDPeerThread;
   end;

  PChatClient = ^TChatClient;

var
  Form1: TForm1;
  MsgQueue, AllClients, BanList, Chatrooms: TObjectList;
  //In diesen Listen werden die Chaträume, User usw. gespeichert und verwaltet
Das läuft dann so ab, dass Client und Server sich zuerst Hallo sagen, der Server einen neuen TChatClient in die Allclients Liste einfügt und dem Client dann einen Raum zuweist. Ein paar wichtige Funktionen, die das erledigen sehen so aus:
(die sind glaube ich nicht das Problem, aber glauben hilft ja nix :-/ )

Delphi-Quellcode:
function InitNewClient(IP: String; AThread: PIdPeerThread): TChatClient;
begin
Result := TChatClient.Create;
with Result do
  begin
   Nickname := IP; //temporär, Namenszuweisung erfolgt im nächsten Schritt
   IPAddr := IP;
   Hash := StringToHash(Nickname+IPAddr); (** im Moment noch sinnlos...vielleicht später nützlich [Präadaption :P]  **)
   Room := AssignLobby; //Sucht bzw. erzeugt die nächste nicht überfüllte Lobby
   Room.ClientsInRoom.Add(@Result); //ob das funtkioniert?
   awaymsg := '';
   dndmsg := '';
   abouttext := '';

   BannedFromRooms := TStringlist.Create;
   IgnoredClients := TStringlist.Create;

   HasIdentified := false;
   IsAdmin := false;
   
   Status := csAvailable;

   Thread := AThread;
  end;
end;

function CreateRoom(designation: string): TChatroom;
begin
Result := TChatroom.Create;
Result.Name := designation;
Result.ClientsInRoom := TList.Create;
end;

function AssignLobby: PChatRoom;
var i: integer;
begin
//Untersuche Räume - Nächste Lobby die weniger als MaxUsersPerRoom User hat wird zurückgegeben
i := 1;
Result := nil;

 While Result=nil do
  begin
   Result := GetChatroomByName('LOBBY-'+IntToStr(i));
   Inc(i);
   If Result = nil then ChatRooms.Add(CreateRoom('LOBBY-'+IntToStr(i)))
    else
     If Result.ClientsInRoom.Count<MaxUsersPerRoom then
       break;
  end;
end;
Das klappt schon ganz ordentlich, nur eine Funktion zickt noch (kann mir aber nicht sicher sein, dass es die einzige ist) :

Delphi-Quellcode:
function GetChatroomByName(RoomName: String): PChatRoom;
var i: Integer;
begin
Result := nil;
 for i:=0 to ChatRooms.Count-1 do
  If (Chatrooms[i] as TChatroom).Name = RoomName then
   begin
    Result := Pointer( (Chatrooms.Items[i] as TChatRoom));
    break;
   end;
end;
Das Problem: Wenn ich diese Funktion aufrufe, gibt sie zwar einen gültigen Zeiger auf *irgendetwas* anderes als nil zurück, allerdings erhalte ich nur "Datenmüll" bei folgendem Test:
ShowMessage(GetChatroomByName('LOBBY-1').Name); ---------------------------
IP Delphi Chat
---------------------------
m‹À¼ÒJ ( + sehr viele Leerzeichen)
---------------------------
OK
---------------------------


Ich hab schon verschiedene Dinge ausprobiert, da ich dachte es stimme etwas von der Logik her mit der GetChatroomByname Funktion nicht, aber eigentlich müsste sie ja das richtige Ergebnis liefern, oder?

Viele Grüße an alle DP'ler und danke schonmal fürs lesen! Normalerweise versuche ich nicht unnötig auszuholen beim posten aber das hier ist schon etwas verzwickt
Dani H.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: (Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 04:13
Hast du auch irgendwo Speicher reserviert für die Daten? Und noch was: Warum sind TChatMessage und TChatRoom Klassen? Sie beinhalten doch keine Methoden, also würde ich da Records nehmen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: (Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 04:23
Am Anfang hatte ich Records benutzt, aber ich konnte leider keine TRecordList finden , daher die Klassen.

Speicher reservieren? Die ganzen Objecte werden von den TObjectLists "geowned" , ich dachte die Sache wäre damit für mich erledigt weil die Methoden der ObjectList die Speicherreservierung und das ganze Management übernehmen...

"Mit TObjectList können Sie eine Liste von Objekten speichern und verwalten. Die Komponente stellt Eigenschaften und Methoden für das Hinzufügen, Löschen, Umsortieren, Suchen, Zugreifen und Sortieren von Objekten zur Verfügung. Ist die Eigenschaft OwnsObjects auf True gesetzt (Voreinstellung), verwaltet TObjectList den Speicher seiner Objekte, das heißt, ein Objekt wird freigegeben, wenn sein Index neu zugewiesen wird, wenn es mit der Methode Delete, Remove oder Clear aus der Liste entfernt wird oder wenn die Instanz TObjectList selbst aufgelöst wird."

Die Objekte werden mit einer Funktion erzeugt und als Ergebnismenge an die Funktion TObjectlist.add() der jeweiligen Liste übergeben.
Delphi-Quellcode:
function CreateObject: TObject;
begin
 Result := TObject.Create;
end;

...

MyObjectList.add(CreateObject);
Muss ich den Pointern auch extra Speicher reservieren mit New() oder genügt das hier?
MyPointer := Pointer(MyObject); Hab ich das falsch verstanden, dass Pointer nur Zeiger auf Objekte (Adressen) sind und eine feste Größe haben (wie z.B. ein Integer 4 Bytes groß ist)?
Dani H.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: (Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 05:31
Also wenn TObjectList so was wie TList ist, dann muss man vor dem Hinzufügen jeweils für das Element Speiucherreservieren. In der Hilfe steht ja auch nur, dass beim Löschen der Speicher freigegeben wird.

MyPointer := Pointer(MyObject); Damit castest du ja nur MyObject nach Pointer. Reservier mal mit new speicher.

Ja Pointer sind monmentan 4 Byte groß.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#5

Re: (Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 09:49
Delphi-Quellcode:
function GetChatroomByName(RoomName: String): PChatRoom;
var i: Integer;
begin
Result := nil;
for i:=0 to ChatRooms.Count-1 do
  If (Chatrooms[i] as TChatroom).Name = RoomName then
   begin
    Result := Pointer( (Chatrooms.Items[i] as TChatRoom));
    break;
   end;
end;
Warum willst du hier einen Zeiger zurueckliefern?
Ein Objekt ist sowieso schon ein Zeiger.
Du lieferst nicht einen Zeiger auf ein TChatroom sondern den TChatroom-Zeiger selbst.
Delphi-Quellcode:
function GetChatroomByName(RoomName: String): TChatroom;
var i: Integer;
begin
Result := nil;
for i:=0 to ChatRooms.Count-1 do
  If (Chatrooms[i] as TChatroom).Name = RoomName then
   begin
    Result := Chatrooms.Items[i] as TChatroom;
    break;
   end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: (Keine) Freude mit Zeigern

  Alt 26. Dez 2003, 15:14
Zitat:
Ein Objekt ist sowieso schon ein Zeiger.
Das wusste ich nicht, danke euch Beiden!!
Es funktioniert jetzt...
Dani H.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:52 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