![]() |
array of X - Suche nach Element
Hallo!
Eigentlich ein Anfängerproblem, aber ich habe scheinbar irgend einen Denkfehler. Ich habe mir eine Art cache gebaut, Cache ist ein Objekt mit Methoden "isCached(name) -> boolean", "addToCache(CacheEntry)" und "getCached(pos) -> CacheEntry". Als Attribut hat diese Klasse ein Array of TCacheEntry, welches im Constructor auf die Länge 0 gesetzt wird (dynamisches array). Hier mal der Code:
Delphi-Quellcode:
und hier die TQueryCacheEntry:
unit QCache;
interface uses ..., QCacheEntry; type TQueryCache = class(TObject) entries: array of TQueryCacheEntry; constructor Create; destructor Destroy; function isCached(name: string; var pos:integer): boolean; function getCached(pos: integer): TQueryCacheEntry; procedure addEntryToCache(Charinfo: TQueryCacheEntry); function getNumEntries: integer; end; var QueryCache: TQueryCache; implementation constructor TQueryCache.Create; begin SetLength(entries,0); end; destructor TQueryCache.Destroy; begin // end; function TQueryCache.getNumEntries: integer; begin Result := Length(entries); end; function TQueryCache.getCached(pos: integer): TQueryCacheEntry; begin if entries[pos] <> nil then Result := entries[pos]; end; function TQueryCache.isCached(name:string; var pos:integer):boolean; var i: integer; begin Result := false; pos := 0; try if Length(entries) > 0 then begin for i := 0 to Length(entries)-1 do begin if entries[i].option1 = name then begin Result := true; pos := i; end; end; end; except Result := false; end; end; procedure TQueryCache.addEntryToCache(Charinfo: TQueryCacheEntry); begin SetLength(entries,Length(entries)+1); entries[Length(entries)-1] := Charinfo; Charinfo.Free; end; end.
Delphi-Quellcode:
unit QCacheEntry;
interface type TQueryCacheEntry = class(TObject) option1: string; option2: string; option3: string; option4: string; option5: string; option6: string; constructor Create; end; implementation constructor TQueryCacheEntry.Create; begin inherited Create; option1:= ''; option2:= ''; option3:= ''; option4:= ''; option5:= ''; option6:= ''; end; end. Problem ist nun dieser Abschnitt, wo ich eine Funktion aufrufe:
Delphi-Quellcode:
Ich bekomme also einen Namen und prüfe, ob dieser Name irgendwo im Cache auftaucht.
procedure TForm1.testName(name:string);
var ... qpos: integer; Charinfo: TQueryCacheEntry; begin qpos := 0; if Cache.isCached(name, qpos) = true then // <- Fehler kommt in dieser Zeile begin ListBox1.Items.Add('Found Object in cache: ' + name + ' in Position: ' + IntToStr(qpos) + ' and total cache size: ' + IntToStr(Cache.getNumEntries)); Charinfo := Cache.getCached(qpos); end else ... Als Fehler bekomme ich die Meldung "...exe raised an exception. Error in Reading of Adress ..." Also für mich sehr nichtssagend. Stehen bleibt er bei der oben markierten Zeile. Problem scheint also diese Methode "isCached" zu sein, die das dynamische Array mit den Cache Einträgen durchläuft, nach einer Übereinstimmung sucht und dessen Position zurückgibt.
Delphi-Quellcode:
Was ist da verkehrt?
function TQueryCache.isCached(name:string; var pos:integer):boolean;
var i: integer; begin Result := false; pos := 0; try if Length(entries) > 0 then begin for i := 0 to Length(entries)-1 do begin if entries[i].option1 = name then begin Result := true; pos := i; end; end; end; except Result := false; end; end; Ich danke für jede Antwort, falls ihr mehr Infos braucht, sagt bescheid. |
Re: array of X - Suche nach Element
In addEntryToCache gibst du das übergebene Objekt frei. Danach steht im Array nur noch Müll.
|
Re: array of X - Suche nach Element
Delphi-Quellcode:
Hallo,
procedure TQueryCache.addEntryToCache(Charinfo: TQueryCacheEntry);
begin SetLength(entries,Length(entries)+1); entries[Length(entries)-1] := Charinfo; Charinfo.Free; end; wie Apollonius scho beschrieben hat gibts du die Instanz wieder frei. Da Du nur die Addresse der Instanz Deinem Array übergeben hast ist auch das Element im Array nicht mehr existent. Vielleicht ist es besser in der addEntryToCache Methode alle Daten von CharInfo zu kopieren. Also ein neues Element im Array erzeugen und dann den Inhalt von CharInfo in das neue Element kopieren. Grüße Klaus |
Re: array of X - Suche nach Element
Super danke euch!
Genau sowas in der Art hatte ich mir gedacht :D |
Re: array of X - Suche nach Element
warum das globale var QueryCache: TQueryCache; ?
die Konstruktoren kannst du dir sparen - dynamische Array und String sind per Standard eh leer leere Destruktoren/Funktionen sind ebenfalls sinnlos getCached liefert einen undefinierten Wert, wenn nichts im Cache ist if Length(entries) > 0 then in isCached bringt auch nichts, denn dieses ist praktisch in der Forschleife schon vorhanden. Try-Except ... eine dort auftretende Exception sollte man nicht einfach unter den Tisch kehren, denn dieses würde auf eine defekte Datenstruktur hinweisen und sowas dürfte eh nie auftreten Vergleiche mit =true macht man nicht :!: (es sei denn man muß GENAU auf True(1) vergleichen)
Delphi-Quellcode:
unit QCache;
interface uses ..., QCacheEntry; type TQueryCache = class(TObject) private entries: array of TQueryCacheEntry; public function isCached(name: string; var pos:integer): boolean; function getCached(pos: integer): TQueryCacheEntry; procedure addEntryToCache(Charinfo: TQueryCacheEntry); function getNumEntries: integer; end; implementation function TQueryCache.getNumEntries: integer; begin Result := Length(entries); end; function TQueryCache.getCached(pos: integer): TQueryCacheEntry; begin //if Assigned(entries[pos]) then // Result := entries[pos] //else // Result := nil; // gekürzt kommt das bei raus und nebenbei wird nun nur noch einmal gesucht :) Result := entries[pos]; end; function TQueryCache.isCached(name:string; var pos:integer):boolean; var i: integer; begin Result := false; for i := 0 to Length(entries)-1 do if entries[i].option1 = name then begin Result := true; pos := i; break; // wenn gefunden, dann braucht man nicht weitersuchen end; end; procedure TQueryCache.addEntryToCache(Charinfo: TQueryCacheEntry); begin SetLength(entries,Length(entries)+1); entries[High(entries)] := Charinfo; end; end.
Delphi-Quellcode:
unit QCacheEntry;
interface type TQueryCacheEntry = class(TObject) option1: string; option2: string; option3: string; option4: string; option5: string; option6: string; end; implementation end.
Delphi-Quellcode:
procedure TForm1.testName(name:string);
var ... qpos: integer; Charinfo: TQueryCacheEntry; begin qpos := 0; if Cache.isCached(name, qpos) then begin ListBox1.Items.Add('Found Object in cache: ' + name + ' in Position: ' + IntToStr(qpos) + ' and total cache size: ' + IntToStr(Cache.getNumEntries)); Charinfo := Cache.getCached(qpos); end else ... |
Re: array of X - Suche nach Element
Moin Peter,
Zitat:
Dann sollte man nur auf "if not Boolscher-Ausdruck then" prüfen. Du könntest übrigens auf Deine eigene Listenimplementierung verzichten, wenn Du Deine Liste nicht von TObject sondern von TObjectList (zu finden in der Unit contnrs) ableitest. Da die Cache-Entries Objekte sind, bietet sich das, meiner Ansicht nach, an. Das dürfte Deine Liste vereinfachen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:54 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 by Thomas Breitkreuz