Frage

Ich hatte diese fiesen Fehler, die in der Vergangenheit verschwunden, aber jetzt nach einiger Zeit zurück.

Ich habe zwei TSAM Objekte (abgeleitet von TPersistent) erzeugt und in ein TAsmJob Objekt geladen (abgeleitet von TObjectList).

Zur Laufzeit erstellt ein Formular ein TStringGrid und dann die AsmJob, die diese beide SAM-Objekte (und lädt einige Daten von der Festplatte in jedem von ihnen) erzeugt. Die AsmJob wird ebenfalls an das Netz zugewiesen. Wenn die Form zerstört wird, nimmt die Grid Pflege der AsmJob indem sie sie zu befreien, die die TSAm Objekte befreit. Hier ist das Problem. Das erste Objekt withot Probleme befreit wird aber die zweite stirbt, wenn seine geerbte Methode (in destructor Zerstören) genannt wird

Ich verwende FreeAndNil im gesamten Programm, um die Objekte zu befreien. Die TSAm Objekte sind nicht NIL !!!!! Also, das ist der erste Versuch, die Objekte zu befreien. Auch die Daten innerhalb der Objekte sind konsistent.

Das Rückgrat des Programms sieht wie folgt aus:

**Create:**

Form -> StringGrid
     -> AsmJob -> Sam1, Sam2
StringGrid.AsmJob:= AsmJob;


**Free:**

Form -> StringGrid -> AsmJob -> Sam1, Sam2

Ich verstehe wirklich nicht, wo ich zu verdoppeln freie versuchen oder das Objekt überschreibt, nachdem es freigegeben wurde.


edit:

Einige der Fehler, die ich habe:

  • FastMM hat einen Fehler während der ein erfasster freier Block Abtastoperation. FastMM festgestellt, dass ein Block gewesen modifiziert nach befreit zu werden.

  • FastMM hat einen Fehler während der ein erfasster freier Block Abtastoperation. Der Block Header beschädigt wurde.

Detail:

The current thread ID is 0x19C, and the stack trace (return addresses) leading to this error is: 
402E77 [System][@FreeMem] 
4068DC [System][@DynArrayClear] 
405E2D [System][@FinalizeArray] 
405D31 [System][@FinalizeRecord] 
40432F [System][TObject.CleanupInstance] 
404272 [System][TObject.FreeInstance] 
404641 [System][@ClassDestroy] 
4D313E [UnitSam.pas][TSam.Destroy][297] 
4042BF [System][TObject.Free] 
4149ED [SysUtils][FreeAndNil] 
4D9C0A [UnitAsmJob.pas][UnitAsmJob][TAsmJob.Destroy][180]  

Ich habe alle "debug" Optionen in der IDE aktiviert, einschließlich der "Range-Check". Auch ist die FastMM4 super aggressiven Debug-Modus eingestellt. Ohne FastMM oder außerhalb des Debuggers läuft das Programm nur in Ordnung - aber doch weiß ich, es bedeutet nicht, dass der Fehler nicht mehr da ist. Eigentlich war es (wahrscheinlich) für mehr als ein ein Jahr, bis ich FastMM installiert haben.


edit:

Danke an alle. Nein, ich fühle ich mich ein bisschen in die richtige Richtung bewege.

Die Struktur des Programms ist es komplizierter ich nur das Rückgrat des ursprünglichen Beitrag klein zu halten angeboten. Aber was zum Teufel, ist es schon bekam größer :) So werden diese TSAm Objekte verwendet, um Daten von der Festplatte zu laden. Eine Datei in jedem Objekt. Sie tun auch einige Verarbeitung und Datenvalidierung. Für jede dieser TSAM habe ich auch ein grafisches Objekt, das auf dem Bildschirm zeigt, (grafisch), die in den Objekten TSAM enthaltenen Daten. Jede Zeile in der TStringGrid zeigt auch die Daten in TSAm, aber textlich.

Eine Frage, die ich habe: wenn ich das Programm in kleinere Stücke brechen, um herauszufinden, wo der Fehler ist, wird der Fehler immer noch angezeigt? Oder es ist möglich, nur in dieser besonderen Konfiguration erscheinen?


Antwort zu „Wie funktioniert die AsmJob zu TStringGrid zugewiesen bekommen, so dass die TStringGrid die AsmJob zerstört, können Sie uns zeigen?“

MyGrid = TStringGrid
  public 
    AsmJob: TAsmJob; 
  end; 

dann irgendwo in der TForm.Create (die Form, die das Gitter hält), das tue ich

MyGrid.AsmJob=AsmJob; 

und im Destruktor des MyGrid ich tun:

begin 
  FreeAndNil(AsmJob); 
  inherited 
end;
War es hilfreich?

Lösung

Dieser Fehler bedeutet, dass Ihr Code internen Speicher Manager Strukturen beschädigt. Ihr Call-Stack stellt den Punkt, wenn MM dies erkannt. Dies ist kein Fehler Pfad oder etwas mit sich bringen. Der tatsächliche Fehler passiert, bevor dieser Moment. Es kann oder kann genannten Klassen nicht in Beziehung gesetzt werden.

Sie sollten versuchen, "Fehler Bereichsprüfung" zu verwenden, Option (don ‚t vergessen Bauen zu machen, nicht kompilieren) und FastMM in voller Debug-Modus (mit CheckHeapForCorruption, CatchUseOfFreedInterfaces и DetectMMOperationsAfterUninstall Optionen aktiviert) .

Sie können auch einschalten FullDebugModeScanMemoryPoolBeforeEveryOperation globale Variable, um einen Fehler fast unmittelbar nach Problem auftritt, aber diese Option verlangsamt Ihre Ausführung viel.

Wahrscheinlich die beste Wahl Anruf ScanMemoryPoolForCorruptions ist in regelmäßigen Abständen. Nennen Sie es an einem Ort. Haben Sie einen Fehler entdeckt? Nennen Sie es früher. bekam noch einen Fehler entdeckt? Nennen Sie es früher wieder. Kein Fehler? Ihr Problem liegt irgendwo zwischen diesen letzten Anrufen. Jetzt können Sie FullDebugModeScanMemoryPoolBeforeEveryOperation Variable zu erhalten genaue Position verwenden. Einfach einschalten nur auf diesen Bereich Code und schalten Sie ihn direkt nach dem Ausschalten.

Es gibt einen sehr ähnlichen Fehler: „FastMM erkannt, dass ein Block, nachdem sie modifiziert wurde, befreit“. In diesem Fall ändert den Code nicht die internen Strukturen, aber auch andere Speicher, die nicht ( „freien Speicher“) verwendet wird.

BTW, Ihre Fehler nicht doppelt frei! Wenn dies ein Doppelfreies Anruf ist, wird FastMM Ihnen sagt, dass ausdrücklich (es ist leicht zu erkennen, wie Sie versuchen, nicht verwendet zu befreien oder Speicherblock-nicht bestanden): „Man hat versucht, zu frei gemacht worden / umverteilen einer nicht zugeordneten Block“.

Andere Tipps

Ein Blockkopf beschädigt zu werden, bedeutet in der Regel Speicher wurde etwas, das überschrieben wird, in der Regel durch eine Art von unsicherem Betrieb zu tun. Sind Sie mit rohen Zeigern oder Assembler-Code in Ihren Aufgaben? Auch, wenn Sie Bereichsprüfung haben und Grenzen ausgeschaltet Prüfung, versuchen, sie auf und Wiederaufbau drehen. Sie helfen, eine Menge von dieser Art von Problem zu fangen.

Es könnte eine logische Rennen irgendwo im Code, wo ein Objekt ist, geschrieben wird, wie sie befreit hat wird. In NULL-Kontrollen und andere IPC-Mechanismen (Lock-Listen usw.), um sicherzustellen, dass nicht der Fall ist.

Eine weitere Option könnte sein, den Code zu Unterklasse, um es hinzuzufügen Anmeldung -. Und prüfen Sie, ob Objekte sequentiell zugegriffen werden

Ein paar Dinge und ich frage, weil ich nicht den Code sehen.

Bei dem folgenden Code:

procedure TForm1.FormCreate(Sender: TObject);
var
   wObjLst : TObjectList;
begin
   wObjLst := TObjectList.Create;
   try
      wObjlst.OwnsObjects := true;
      wObjlst.Add(TPersistent.Create);
      wObjlst.Add(TPersistent.Create);
   finally
      freeandnil(wObjlst);
   end;
end;

Dies funktioniert mit Überschreitungsfehler.

Sie erklären, dass

  

Zur Laufzeit erstellt ein Formular ein TStringGrid und dann die AsmJob des   schafft diese beiden SAM-Objekte (und einige Daten von der Festplatte in jedem Laden von   Sie). Die AsmJob wird ebenfalls an das Netz zugewiesen. Wenn die Form zerstört,   das Gitter übernimmt den AsmJob indem sie sie zu befreien, die die TSAm befreit   Objekte. Hier ist das Problem: das erste Objekt withot Probleme befreit   aber die zweite stirbt, wenn ihre geerbten Methode (in Zerstören   destructor) aufgerufen wird.

Meine erste Frage ist, wie sich die AsmJob zu TStringGrid zugewiesen bekommen, so dass die TStringGrid die AsmJob zerstört, können Sie uns zeigen?

Zweitens, warum ein Nachkomme von TObjectList schaffen, um es zwei Objekte zu speichern und sie dann frei, sie selbst zu befreien, anstatt zu schaffen und lassen die TObjectList sie zerstören, wie oben gezeigt.

Die andere Sache ist zu versuchen, das volle FastMM4 Paket von fastmm.sourceforge.net zum Download , installieren sie sie und die fulldebug dLL verwenden, um genau zu verfolgen, was Objekt versagt. Du und ich davon aus, dass es eines der SAM-Objekte ist und es kann oder auch nicht sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top