AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FastMM4 - Verbuggt?

Ein Thema von Snaeng · begonnen am 6. Okt 2008 · letzter Beitrag vom 6. Okt 2008
Antwort Antwort
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
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:13
FastMM4 wirft mit Absicht eine Exception, damit das fehlerhafte Programm nicht weiterläuft bzw. Du an die Stelle findest, an der das Problem auftritt.

In deinen Records sollte kein dynamischer String deklariert werden, sondern immer ein Statischer: Ändere mal die Deklaration des Records
delphi]
TMapData = record
Name : String;
Fieldsize : Word;
BgColor : TColor;
Images : array [ftWater..ftDestroyable] of String; // <<<< Möööööppp
end; [/delphi]

Frage: Wieso verwendest Du nicht einfach dynammische Arrays?
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Snaeng

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

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:19
Hallo.

Danke erstmal für deine Antwort.

Ich habe vergessen den Record aus dem Code zu entfernen. Wie man sehen kann ist er noch garnicht enthalten.

Ich benutze dynamische Arrays nicht, da sie nach der Aufgabenstellung verboten sind. Warum auch immer... Und da ich ebenfalls die Compiler-Direktive HugeStrings abgeschaltet habe, hat String auch keine dynamische Größe.

Das Problem ist ja: Warum wirft FastMM4 eine Exception?
An FreeMem(Data); ist doch nichts falsch?! Auch wenn ich die Größe jeweils angebe kommt diese Fehlermeldung.



Snaeng
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:23
FastMM erzeugt im Debugmodus um jeden Speicherblock Schutzblöcke. Wird der Speicherblock frei gegeben wird dieser Block auf Unversehrtheit überprüft und wenn diese nicht der Fall ist eine Fehlermeldung erzeugt um Aufzuzeigen das dein Programm über den reservierten Block hinaus geschrieben hat. Das ohne FastMM das nicht auftritt heißt nur das der alte Memorymanger von alten Delphi-Versionen einfach sowas nicht erkannt hat und dein Progamm stattdessen irgendwan mal irgendwas komisches macht.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Snaeng

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

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:27
Aber wo in meinem Code tritt denn dieser Fehler auf? Soweit ich das sehe ist doch alles in Ordnung, ich überschreibe keinen unreservierten Speicher und ich gebe den Speicher immer frei.

Code:
  List := TMemMap.Create;
  List.ChangeSize(2, 2);
  List.AddRow(1);
  List.Echo;
  List.Free
Damit teste ich die Klasse übrigens. Und eben bei List.Free - wenn der Destruktor aufgerufen wird - tritt diese Fehlermeldung auf. Sie tritt allerdings nicht auf, wenn ich AddRow nicht aufrufe - Egal wie oft ich ChangeSize aufrufe. Also mit ChangeSize sollte alles in Ordnung sein.


Snaeng
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#6

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:43
Ich hab den Quelltext jetzt gerade mal überflogen und mir ist da was aufgefallen:
Delphi-Quellcode:
procedure TMemMap.ChangeSize(NewRows, NewCols : Word);
begin
  begin
    for Row := 0 to NewRows - 1 do
    begin
      for Col := 0 to NewCols - 1 do // <-- hier gehst du bis NewCols - 1
    end
  end;
end;
und hier
Delphi-Quellcode:
procedure TMemMap.AddRow(PrevRow : Word);
begin
  for Row := 0 to PrevRow - 1 do
    for Col := 0 to Cols do // <-- hier gehst du bis Cols und nicht Cols-1
end;
Ich hab jetzt nicht genau genug hingeschaut, jedoch das ist schon auffällig.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat
Snaeng

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

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 13:45
Genau das ist mir jetzt gerade auch aufgefallen!
Ständig angeschaut und überprüft, aber genau das immer übersehen...

Danke danke! Endlich Problem gelöst.
Lag also doch nicht an FastMM4 *G*.



Happy Snaeng
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: FastMM4 - Verbuggt?

  Alt 6. Okt 2008, 15:01
Zitat von Snaeng:
Lag also doch nicht an FastMM4 *G*.
Im Gegenteil!
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz