Einzelnen Beitrag anzeigen

Snaeng

Registriert seit: 6. Okt 2008
4 Beiträge
 
Delphi 2007 Professional
 
#1

FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:00
Hallo erstmal.

Das ist meine erste Frage in diesem Forum, also bitte nicht gleich lynchen wenn ich in der falschen Area gepostet habe (dies scheint die richtige zu sein für diese Frage).


Also und zwar möchte ich eine Klasse schreiben, die ein Spielfeld speichert. Diese soll jeweils einen Wert pro Feld speichern. Dies möchte ich direkt im Speicher realisieren und nicht als verkettete Liste. Da es sich um eine Schulaufgabe handelt und wir leider ein paar dämliche restriktionen haben, dürfen wir dynamische Arrays nicht benutzen.

Nun ja, soweit läuft die Klasse auch. Die größe lässt sich mit der ChangeSize Prozedur problemlos verändern. Allerdings macht die AddRow Prozedur Probleme, die eine neue Zeile an beliebiger Stelle einfügen soll. Wenn ich diese Prozedur ausführe, gibt mir FastMM (und Delphi) eine Fehlermeldung bei dem Befehl FreeMem(Data); im Destruktor. FastMM sagt "The block footer has been corrupted." und Delphi wirft die Exception EInvalidPointer mit der Nachricht 'Ungültige Zeigeroperation.'. Delphi wirft allerdings keine Exception wenn ich FastMM nicht mit in das Programm kompiliere.

Nun frage ich mich ob dies ein Problem mit FastMM ist (da ohne keine Exception auftritt), oder ob wirklich was mit dem Code nicht stimmt.

Hier ist der gesamte Code der Unit:

Code:
unit UMemMap;

interface
uses SysUtils, Graphics;

type PFType     = ^TFType;
     TFType     = (
                     ftFree,
                     ftWater,
                     ftUndestroyable,
                     ftDestroyable
                   );
     TMapData   = record
                     Name     : String;
                     Fieldsize : Word;
                     BgColor  : TColor;
                     Images   : array [ftWater..ftDestroyable] of String;
                   end;
     TMemMap    = class
                     private
                       Data : Pointer;
                       Rows,
                       Cols : Word;

                     public
                       destructor Destroy; override;

                       procedure AddRow(PrevRow : Word);

                       procedure ChangeSize(NewRows, NewCols : Word);
                       procedure UpdateField(Row, Col : Word; FType : TFType);

                       procedure Echo;
                   end;


implementation

destructor TMemMap.Destroy;
begin
  FreeMem(Data);

  inherited
end;


procedure TMemMap.AddRow(PrevRow : Word);
var NewData : Pointer;
    Row,
    Col    : Integer;
begin
  GetMem(NewData, (Rows + 1) * Cols * SizeOf(TFType));

  for Row := 0 to PrevRow - 1 do
    for Col := 0 to Cols do
      PFType(Integer(NewData) + (Row * Cols + Col) * SizeOf(TFType))^ :=
        PFType(Integer(Data) + (Row * Cols + Col) * SizeOf(TFType))^;

  for Col := 0 to Cols do
    PFType(Integer(NewData) + (PrevRow * Cols + Col) * SizeOf(TFType))^ := ftFree;

  for Row := PrevRow + 1 to Rows do
    for Col := 0 to Cols do
      PFType(Integer(NewData) + (Row * Cols + Col) * SizeOf(TFType))^ :=
        PFType(Integer(Data) + ((Row - 1) * Cols + Col) * SizeOf(TFType))^;

  FreeMem(Data);
  Inc(Rows);
  Data := NewData
end;


procedure TMemMap.ChangeSize(NewRows, NewCols : Word);
var NewData : Pointer;
    Row,
    Col    : Integer;
begin
  if (NewRows = 0) or (NewCols = 0) then
    NewData := nil
  else
  begin
    GetMem(NewData, NewRows * NewCols * SizeOf(TFType));

    for Row := 0 to NewRows - 1 do
    begin
      for Col := 0 to NewCols - 1 do
        if (Col > Cols - 1) or (Row > Rows - 1) then
          PFType(Integer(NewData) + (Row * NewCols + Col) * SizeOf(TFType))^ := ftFree
        else
          PFType(Integer(NewData) + (Row * NewCols + Col) * SizeOf(TFType))^ :=
            PFType(Integer(data) + (Row * Cols + Col) * SizeOf(TFtype))^
    end
  end;
                   
  FreeMem(Data);
  Rows := NewRows;
  Cols := NewCols;
  Data := NewData
end;

procedure TMemMap.UpdateField(Row, Col : Word; FType : TFType);
begin
  PFType(Integer(Data) + ((Row - 1) * Cols + (Col - 1)) * SizeOf(TFType))^ := FType
end;

procedure TMemMap.Echo;
var Row, Col : Integer;
begin
  writeln('Ausagbe: ', Cols, 'x', Rows);

  for Row := 0 to Rows - 1 do
  begin
    for Col := 0 to Cols - 1 do
      write(Word(PFType(Integer(Data) + (Row * Cols + Col) * SizeOf(TFType))^), ' ');

    writeln
  end;

  writeln
end;

end.
Kann mir jemand vielleicht helfen?

Sollte es wirklich an FastMM liegen: Gibt es noch gute Alternativen um Speicherlecks festzustellen?



Mit freundlichen Grüßen
Snaeng


Edit: Es handelt sich übrigens um die Version 4.90 von FastMM.
  Mit Zitat antworten Zitat