Einzelnen Beitrag anzeigen

me2u
(Gast)

n/a Beiträge
 
#1

Speicherproblem mit Dispose

  Alt 3. Mai 2007, 03:59
Hallo zusammen,

ich habe hier ein kleines "Speicherproblem", dessen Ursache ich mir nicht so genau erklären kann: Das Programm besteht aus einer einfach verketteten Liste, die auf Knopfdruck mit 50000 Elementen gefüllt wird und ebenfalls auch wieder auf Knopfdruck entleert werden kann.
Sofort nach Programmstart benötigt das Programm ca. 3.500K Speicher. Nach dem Befüllen ca. 16.100K und nun das seltsame... nach dem Entleeren der Liste immer noch ca. 7300K. Warum fällt der Speicherbedarf nach dem entleeren der Liste nicht wieder auf die ursprünglichen 3500K zurück (oder zumindest annähernd auf diesen Wert)? Ist es ein Programmierfehler, den ich übersehe?

MfG
Markus

Hier mal der Code:

Delphi-Quellcode:
type
  [...]
  PRegEntry = ^TRegEntry;
  TRegEntry = record
    Key: Cardinal;
    KeyName: string;
    next: PRegEntry;
  end;

var
  Form1: TForm1;
  RegListAnchor: PRegEntry;

[...]

function GetKeyName(hKey: HKEY): string;
var now: PRegEntry;
begin
  Result := 'Error';
  if (RegListAnchor <> nil)
    then begin
      now := RegListAnchor;
      while (now^.next <> nil) and (now^.Key <> hKey) do
        now := now^.next;
      if now^.Key = hKey then Result := now^.KeyName;
    end;
end;

function AddRegEntry(const hKey: HKEY; KeyName: string): Boolean;
var now, newEntry: PRegEntry;
begin
  Result := False;
  if RegListAnchor = nil
  then begin // noch kein Eintrag in der Socket-Liste
    New(newEntry);
    newEntry^.Key := hKey;
    newEntry^.KeyName := KeyName;
    newEntry^.Next := nil;
    RegListAnchor := newEntry;
    Result := True;
  end
  else begin // schon Elemente in der Socket-Liste
      now := RegListAnchor;
      while (now^.next <> nil) and (now^.Key <> hKey) do
        now := now^.next;
      if now^.Key = hKey
      then begin
        now^.KeyName := KeyName;
        Result := True;
      end
      else begin
        New(newEntry);
        newEntry^.Key := hKey;
        newEntry^.KeyName := KeyName;
        newEntry^.Next := RegListAnchor;
        RegListAnchor := newEntry;
        Result := True;
      end;
    end;
end;

function DeleteRegEntry(hKey: HKEY): Boolean;
var davor, pos: PRegEntry;
begin
  Result := False;
    if (RegListAnchor <> nil) // nur löschen, wenn überhaupt Einträge in Liste
    then begin
      pos := RegListAnchor;
      if RegListAnchor^.Key = hKey // 1.Element = zu löschender Eintrag ?
      then begin
        RegListAnchor := RegListAnchor^.next;
        Dispose(pos);
        Result := True;
      end
      else begin // zu löschender Eintrag is nich Listenanfang
        if RegListAnchor^.next <> nil // wenn nur ein Eintrag und der verschieden von zu löschendem Element is => Nix zu löschen
        then begin
          pos := RegListAnchor^.next;
          davor := RegListAnchor;
          while (pos^.next <> nil) and (pos^.Key <> hKey) do begin
            davor := pos;
            pos := pos^.next;
          end;
          if pos^.Key = hKey then begin
            davor^.next := pos^.next;
            Dispose(pos);
            Result := True;
          end;
        end;
      end;
    end;
end;

function GetAllEntries: string;
var pos: PRegEntry;
begin
  Result := '{';
  if (RegListAnchor <> nil)
  then begin
    pos := RegListAnchor;
    while pos<>nil do begin
      if Result = '{'
      then Result := Result + IntToStr(pos^.Key)
      else Result := Result + ', ' + IntToStr(pos^.Key);
      pos := pos^.next;
    end;
  end;
  Result := Result + '}';
end;

[...]

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
  Memo1.Lines.Clear;
  for i := 1 to 50000 do begin
    AddRegEntry(i, 'MAiluglugklhgkhvljhblkjhigjhvb,jhvkhgfljghgizt975hgkhhitz59hgjkhkgvnbvkhgfkghvb kvfghkjlhzgulzguzgut67tuzhgkjbh87thujbljhb87tzjhbjhb8tjhbkuzg87jhbo87tiuhb,jhg8o7tjlhbo87tvkghvkuzgvhb khgvkvb kgvuvrkus');
  end;
  Memo1.Lines.Clear;
  Memo1.Lines.Add(GetAllEntries);
end;

procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
begin
  Memo1.Lines.Clear;
  for i := 50000 downto 1 do DeleteRegEntry(i);
  Memo1.Lines.Clear;
  Memo1.Lines.Add(GetAllEntries);
end;
  Mit Zitat antworten Zitat