3 Stimmen

Ungültige Zeigeroperation, Hinweis mit Debugging angefordert

Ich scheine Code erstellt zu haben, der den Speicher zerstört.

Da ich noch nie solche Probleme hatte, setze ich jetzt eine Invalid Pointer Operation.

Im Folgenden wird der Wert der Konstanten Zeichenkette sFilename nach dem Aufruf von PromptForXYZPropertiesSettings verworfen.

// Allow the user to quickly display the properties of XYZ without needing to display the full Editor
function PromptForXYZProperties(const sFilename:string; var AXYZProperties: TXYZProperties): boolean;
var
  PropEditor: TdlgEditor;
begin
  PropEditor:= TdlgEditor.create(nil);
  try
    PropEditor.LoadFromFile(sFilename);                   <-- sFilename = 'C:\My Folder\Some Folder.txt'
    PropEditor.SelectedXYZProperties := AXYZProperties;

    // Bypass PropEditor to show form owned by it
    Result := PropEditor.PromptForXYZPropertiesSettings;  

    if Result then
    begin
      PropEditor.SaveToFile(sFilename);                   <-- sFilename now somethign like 'B'#1#0#0'ë' or value of a different var
    end;
  finally
    PropEditor.free;      
  end;
end;

Andere Details:

  • Delphi 2007, Windows 7 64 Bit, aber kann beim Testen der EXE auf XP reproduzieren
  • ENTFERNEN von CONST STOPPT PROBLEM VOM AUSSTELLEN (aber vermutlich lauert das lauert das Problem also nur)
  • PropEditor.PromptForXYZPropertiesSettings erstellt und zeigt ein Formular an. Wenn ich den ShowModal-Aufruf deaktiviere, wird der wird der Speicher nicht gelöscht. Auch wenn ich alle Steuerelemente und Code aus dem Formular aus dem Formular

Ich hätte also gerne einen Rat, wie man das Problem beheben kann. Ich dachte, vielleicht beobachten die Speicher-Zeiger, wo die sFilename var vorhanden ist, um zu sehen, wo es gelöscht wird, aber nicht sicher, wie ich das tun würde (offensichtlich muss innerhalb der app getan werden, so ist Speicher im Besitz).

Danke

6voto

Mason Wheeler Punkte 79858

Klingt für mich so, als würde etwas Ihren Stack zerstören. Bei einem flüchtigen Blick auf Ihren Code kann ich keine offensichtlichen Probleme mit der Korrektheit erkennen. Sie haben die richtige Idee: Um das Problem aufzuspüren, müssen Sie den Wert Ihrer Zeichenkette überwachen und sehen, wann er sich ändert. So machst du das:

  • Setzen Sie einen Haltepunkt in der ersten Zeile Ihrer Methode.
  • Wenn er abbricht, sehen Sie sich die Ansicht "Lokale Variablen" im Debugger an. Suchen Sie sFilename und doppelklicken Sie darauf.
  • Das Fenster Debug-Inspector wird geöffnet. Oben steht etwas in der Art wie hier: sFileame: string $18FEA8 : $4A0E5C . Diese beiden Hexadezimalwerte sind die Positionen des Verweises auf die Zeichenkette bzw. die Zeichenkettendaten selbst.
  • Drücken Sie CTRL-ALT-B, um die Haltepunktliste aufzurufen. Sie hat eine kleine Symbolleiste, und die erste Schaltfläche auf der Symbolleiste hat einen Dropdown-Pfeil.
  • Klicken Sie auf diesen Pfeil und wählen Sie Data Breakpoint aus der Liste. Sie möchten zwei Haltepunkte erstellen, einen für jeden der beiden Werte im Fenster Debug-Inspector. (Wenn Sie davor gewarnt werden, einen Daten-Haltepunkt auf dem Stack zu setzen, tun Sie es trotzdem, aber denken Sie daran, ihn anschließend zu löschen).
  • Sobald Sie die beiden Daten-Haltepunktwerte festgelegt haben, drücken Sie F9. Das System überwacht diese Speicherstellen und unterbricht, wenn sie geändert werden. Von dort aus sollten Sie in der Lage sein, herauszufinden, was Ihre Zeichenfolge beschädigt hat.

1voto

Viktor Svub Punkte 1431

Ich vermute, dass ein Code in der TdlgEditor.LoadFromFile (oder weiter unten im Aufrufstapel) über einen Zeiger auf die Zeichenkette zugreift (in diesem Fall kann der Compiler nicht die const -heit).
string / AnsiString Variablen sind in der Tat ref-gezählte Datensätze, die vom Compiler intrinsisch gehandhabt werden und sollten niemals durch Zeigerzugriff geändert werden.
Solange Sie nicht in der Lage sind, die TdlgEditor Klasse, könnte Ihre Lösung tatsächlich richtig sein - Sie erstellen eine lokale Kopie der Zeichenkette und müssen sich nicht darum kümmern, ob sie während des Prozesses zerstört wird, Sie müssen nur daran denken, die pas nichts über den Inhalt der lokalen Zeichenfolge nach dem Aufruf annehmen.

0voto

Alex Punkte 5325

In der Regel treten ungültige Zeigeroperationen auf, wenn Sie ungültige Zeiger an MM-Routinen übergeben. Zum Beispiel wird der Speicher zweimal freigegeben. Eine Speicherbeschädigung führt in der Regel zu einer Zugriffsverletzung.

Ich denke, Sie sollten damit beginnen, die Fehlersuche im Speichermanager im Debug-Modus .

0voto

Deltics Punkte 21121

Ich nehme an, dass Ihr PromptForXYZPropertiesSettings ruft intern ShowModal() und wenn TdlgEditor wird bei Abschluss auf Frei gesetzt ( FormClose Ereigniseinstellung CloseAction := caFree ), dann wird, wenn der Ausführungsfluss zu Ihrem Code zurückkehrt, die dlgEditor Objekt ist bereits zerstört und daher ungültig.

Dies könnte auch die ungültige Zeigeroperation erklären, da Sie versuchen würden, einen bereits Free Objekt in der finally dlgEditor.Free Code.

Wenn das der Fall ist, sollten Sie Ihre TdlgEditor nur in geschlossenem Zustand ausblenden, indem Sie CloseAction := caHide im Ereignis FormClose.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X