Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#3

Re: Funktion verursacht Memory-Leak >>> Warum ?

  Alt 30. Jun 2006, 21:48
ein "anfälliger" Programmierstil den du hast

Delphi-Quellcode:
function RemoveChars(const Rufnummer: String): String;
var
  I: Integer;
  R,T: String;
begin
  R := '';
  if Rufnummer <> 'then
  begin
    T := StringReplace(Rufnummer, '+', '00', []);
    for I := 1 to Length(T) do
      if T[I] in ['0'..'9'] then
        R := R + T[I];
  end;
  Result := R;
end;
Was auffällt ist die klarere Struktur einer modularen Programmierung. Das heist klare Eingabeparameter die readonly/konstant sind, klare lokale Variablen in denen das Prozessing stattfindet und klare Ausgabeparameter die am Schluß der Funktion erst gefüllt werden, quasi-konstant.
Dann die Benutzung struktutierter Bedingungen, statt einem Exit also ein Begin End Block.
Und die Benutzung lesbarer Char Konstanten in der in [] Abfrage, was im Gewgensatz zu #48 und #57 oder wenigsten #$30 und #$39 weit intuitiver ist. Diese Kleinigkeiten machen alles verständlicher und wir als Programmierer können das bischen Glukose in unserem Hirn auf die logische Fehlervermeidung konzentrieren.

Klar, es gibt nun noch Optimierungen zu Gunsten der Performance, aber das ist für dein Problem erstmal irrelevant.
Zb.

Delphi-Quellcode:
function RemoveChars(const Rufnummer: String): String;
var
  I,J: Integer;
  R: String;
begin
  R := '';
  if Rufnummer <> 'then
  begin
    J := 0;
    SetLength(R, Length(Rufnummer) * 2); // doppelte Länge preallozieren, bei '+' Substitution mit '00' ergo 1 zu 2
    for I := 1 to Length(Rufnummer) do
      if Rufnummer[I] in ['0'..'9'] then
      begin
        Inc(J);
        R[J] := T[I];
      end else
        if Rufnummer[I] = '+then
        begin
          R[J +1] := '0';
          R[J +2] := '0';
          Inc(J, 2);
        end;
    SetLength(R, J);
  end;
  Result := R;
end;
Diese Funktion prealloziert den LongString in R schon im vorhinein. Statt per Konkatenation -> R := R + x nun viele Reallozierungen dieses String durchzuführen (jedesmal ein Aufruf zum Speichermanager und auch Kopieren dieses Speicherbereich), kopieren wir nur noch das entsprechende Zeichen. Am Schluß setzen wir die Länge von R nur noch auf die Anzahl tatsächlich kopierter Zeichen. Das dürfte in der Peformance weitaus effizienter sein.


Gruß Hagen
  Mit Zitat antworten Zitat