Announcement

Collapse
No announcement yet.

Funtion mit tstrings als Ergebnis???

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Funtion mit tstrings als Ergebnis???

    Hi ich versuche gerade einen Baum durchzugehen und aus jedem Eintrag einen String auszulesen. Die Strings sollen dann schliesslich einer Combobox zugewiesen werden. Dazu packe ich das Ergebnis der Function bereits in eine Stringliste. Die Function ruft sich Rekursiv auf. Demnach werden die Strings immer größer. Leider scheitert aber bereits beim ersten Aufruf der Function jegliche zuweisung. ein result.clear gibt einen ZUgrifffehler, genau wie alle anderen Zugriffe.. Jemand eine Idee??

  • #2
    Ok Fehler gefunden...

    man sollte es mit

    tstringlist.create versuchen statt mit tstrings.create

    hat sich also erledig

    Comment


    • #3
      Die Delphi-"Standard"-Vorgehensweise für dein Problem wäre,
      nicht eine Funktion mit Stringliste als Rückgabewert, sondern eine
      Prozedur mit TStrings als Übergabeparameter. In der Routine hängst
      du dann nur an die übergebene Liste an. Auf die Tour gibt's weniger
      Verwirrung, wer die Liste erzeugen oder zerstören muss, und du sparst
      dir einige Kopieraktionen (besonders wenn deine Routine rekursiv sein soll). Beispiel: Standardanwendung mit TMemo, TEdit und TButton drauf, dazu folgender Code:
      <pre class="sourcecode"><code>
      <b>procedure</b> AddNumbers(AList: TStrings; i: Integer);
      <b>begin</b>
      AList.Add(IntToStr(i));
      <b>if</b> i &gt; 0 <b>then</b>
      AddNumbers(AList, i - 1);
      <b>end</b>;
      <br>
      <b>procedure</b> TForm1.Button1Click(Sender: TObject);
      <b>begin</b>
      Memo1.Clear;
      AddNumbers(Memo1.Lines, StrToIntDef(Edit1.Text, 10));
      <b>end</b>;
      </code></pre>
      HTH, Uli

      Comment


      • #4
        hm....

        es klappt nu wunderbar rekursiv. aber die Frage ,mit dem erzeugen und zerstören habe ich mich auch schon gefragt wie das klappt und ob ich da nicht ein paar nette Speicher Leichen lasse. Aber leider habe ich mich mit dem Thema eh erst wenig beschäftigt.

        Mein Programm sieht nun wie folgt aus:
        <pre>
        Function tbaum.drin2: tstrings;
        Begin
        result := tstringlist.Create;
        If inhalt = nil then result.Clear
        else Begin
        If links = nil then
        If rechts = Nil then Begin
        result.clear;
        result.add(tstring50(inhalt^));
        nummer := i;
        inc(i);
        end
        else Begin
        result.Clear;
        result.add(tstring50(inhalt^));
        nummer := i;
        inc(i);
        result.AddStrings (rechts.drin2);
        end
        else
        If rechts = nil then Begin
        result.Clear;
        result.add(tstring50(inhalt^));
        nummer := i;
        inc(i);
        result.addStrings (links.drin2);
        end
        else begin
        result.Clear;
        result.add(tstring50(inhalt^));
        nummer := i;
        inc(i);
        result.addStrings (links.drin2);
        result.addStrings (rechts.drin2);
        end;
        end;
        End;
        </pre>

        Es wird ein Binärer Baum durchlaufen. Aus jeder "Etage" wird ein String ausgelesen. i ist eine globale variable. Über sie wird jedem gesicherten Eintrag eine eindeutige Zahl zugewiesen. Diese ist gleichzeitig die Position in der Stringliste.

        Bisher funktioniert es so ganz gut, frage eben nur: bleibt was im Speicher, wenn ja kann ich es löschen??

        Ich hoffe man wird aus meinen Code ein wenig schlau, wüsste nun nicht wie ich das erklären sollte

        Bis denne Christophe

        Comment


        • #5
          Hi Christopher,<br>
          ich hab deine Routine jetzt nur mal schnell überflogen, aber ich glaube, du hinterläßt
          eine Spur von Leichen &lt;g&gt; hinter dir zurück, z.B. wird in der Zeile
          <tt>result.addStrings (links.drin2);</tt> innerhalb von <tt>links.drin2</tt>
          eine Stringliste erzeugt (erste Zeile der Routine), diese Liste wird als Übergabeparameter
          an AddStrings verwendet, aber nie aufgeräumt. Also wenn du die Stringliste unbedingt
          <b>in</b> "Drin2" erzeugen willst, dann muss der Aufruf
          wenigstens so ähnlich aussehen:<pre>
          TemporaereStringListe := links.drin2;
          result.addStrings(TemporaereStringListe);
          TemporaereStringListe.Free;
          </pre>
          Das ist aber IM(NS)HO Quatsch: Bei jeder Rekursionsebene erzeugst du Stringlisten,
          kopierst sie, löschst sie wieder -- das ist ein Heidenaufwand zur Laufzeit,
          den du dir mit dem Ansatz aus meinem ersten Posting sparen kannst:
          Erzeuge <b>eine</b> Stringliste (du willst am Ende ja auch nur eine haben),
          und hänge einzelne Strings an, statt komplette Stringlisten zu kopieren.
          <p>Was du mit der "Etagennummer" (Variablen i und nummer) anstellst, hab ich nicht
          recht kapiert, aber auch da würde ich i.a. einen Übergabeparameter (evtl. per "var" übergeben)
          einer globalen Variablen vorziehen -- ähnlich wie das "i" in meinem AddNumbers.
          <p>BTW: Nach memory leaks kannst du z.B. mit MemProof suchen (http://www.automatedqa.com/downloads/memproof.asp).
          <p>Ciao, Uli

          Comment


          • #6
            jo thx.. werde das dann nochmal umschreiben aber dann weiß ich nu auch wenigstens wie das mit dem Speicher Freigeben wieder geht.

            Das was ich hier mache is eh alles Schulprogrammierung und damit eher zum testen für mich als für ein sinnvolles Proggie gedacht ^

            Comment

            Working...
            X