AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Memoryleak oder fatale Exception bei TJSONObject.RemovePair

Memoryleak oder fatale Exception bei TJSONObject.RemovePair

Ein Thema von t2000 · begonnen am 8. Mär 2025 · letzter Beitrag vom 10. Mär 2025
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#1

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 8. Mär 2025, 23:11
Solltest du an dieser Stelle nicht einen Clone des TJSONValue verwenden?
Delphi-Quellcode:
  if HasValue( AJSONObject, AName) and not HasValue( AJSONObject, AName + cXDataRef) then
    // dann neuer Eintrag mit ref anhängen
    AJSONObject.AddPair( AName + cXDataRef, AJSONObject.Values[ AName]);
Immerhin wird das Pair aus dem der Value stammt ja direkt danach freigegeben:
Delphi-Quellcode:
  if HasValue( AJSONObject, AName) then
    AJSONObject.RemovePair( AName).Free; // <=== hier nach ist der Zugriff auf AJSONObject nicht mehr möglich, da gelöscht.
Mir stellt sich überhaupt die Frage: Wieso änderst du nicht einfach den Namen des Pairs von AName auf AName + cXDataRef?

Bei CheckIDValue verwendest du einen string als Speicher für den Value-Inhalt, deswegen gibt es dort kein Problem.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 15. Dez 2005
Ort: NRW
247 Beiträge
 
Delphi 12 Athens
 
#2

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 9. Mär 2025, 07:28
... Stunden später ...

ne, die entscheidende Routine extrahiert und den Fehler gefunden. JSON ist schon sehr tückisch.

Der Fehler liegt hier: AJSONObject.AddPair( AName + cXDataRef, AJSONObject.Values[ AName]); Dort wird nicht der String des alten Feldes dem neuen Feld zugewiesen, sondern eine Referenz auf den Wert des alten Wertes. (!!)
Indem ich "AJSONObject.Values[ AName]" einsetze, setze ich nur einen Link.

Richtig wäre es:
Delphi-Quellcode:
var
  tempStr: String;
begin
  // vor dem Löschen
  tempStr := AJSONObject.Values[ AName].Value;
  AJSONObject.AddPair( AName + cXDataRef, tempStr);
Nun ist alles sauber. Kein Fehler und auch kein Memoryleak.

Also: Bei TJSONObject.RemovePair IMMER das gelöschte Pair freigeben! Aber sicher gehen, dass keine Referenz mehr auf dieses Pair existiert.

Danke. Uwe hat es erkannt.
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!

Geändert von t2000 ( 9. Mär 2025 um 07:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 15. Dez 2005
Ort: NRW
247 Beiträge
 
Delphi 12 Athens
 
#3

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 9. Mär 2025, 07:29

Mir stellt sich überhaupt die Frage: Wieso änderst du nicht einfach den Namen des Pairs von AName auf AName + cXDataRef?
So weit ich weiß, geht das nicht, oder?

Namensänderung in (Standard-)Delphi nicht möglich.
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#4

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 9. Mär 2025, 09:47
Klar geht das:
Delphi-Quellcode:
procedure Main;
begin
  var obj := TJSONObject.Create;
  try
    obj.AddPair('MyName', 'Uwe');
    Writeln(obj.ToJSON);
    var pair := obj.Pairs[0];
    pair.JsonString := TJSONString.Create('MyFullName');
    pair.JsonValue := TJSONString.Create('Uwe Raabe');
    Writeln(obj.ToJSON);
  finally
    obj.Free;
  end;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 15. Dez 2005
Ort: NRW
247 Beiträge
 
Delphi 12 Athens
 
#5

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 9. Mär 2025, 14:37
Das werde ich ausprobieren.
Ich hatte die Information von 2 unterschiedlichen Stellen. (im Internet; und fragt bitte nicht wo; ich weiß es nicht mehr)

Aktuell liefert ChatGPT o3-mini-high dies hier:
Screenshot 2025-03-09 153102.jpg
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#6

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 9. Mär 2025, 15:15
Der Hinweis "Nur das Paar, nicht den Wert" ist allerdings Unsinn.

Aber nun haben die vielen AI Agenten ja wieder Futter für neue Erkenntnisse.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 10. Mär 2025, 09:33
Das werde ich ausprobieren.
Ich hatte die Information von 2 unterschiedlichen Stellen. (im Internet; und fragt bitte nicht wo; ich weiß es nicht mehr)

Aktuell liefert ChatGPT o3-mini-high dies hier:
Anhang 57430
DeepSeek sagt einen direkt, dass da in CheckXDataRef eine Dangling Reference existiert (so wie sie auch Uwe erkannt hat).

Zitat:
Mein Prompt:
Kontext ist Softwareentwicklung mit Delphi, speziell der Umgang mit JSON. Findest du im folgenden Quelltext mögliche Fehler?

...es folgt dann dein Codeabschnitt.
Zitat:
Hier sind die möglichen Fehler im Quelltext:

1. Dangling Reference in `CheckXDataRef`:
- **Problem**: Beim Hinzufügen des neuen JSON-Paars (`AddPair`) wird der Wert des ursprünglichen Paars (`AJSONObject.Values[AName]`) direkt übernommen. Nach dem Löschen und Freigeben des ursprünglichen Paars (`RemovePair(...).Free`) wird dieser Wert freigegeben, sodass das neue Paar auf ungültige Daten verweist.
- **Lösung**: Den Wert klonen (z. B. `AJSONObject.Values[AName].Clone`), um eine unabhängige Kopie zu erstellen.


Delphi-Quellcode:
   // Korrektur:
   AJSONObject.AddPair(AName + cXDataRef, AJSONObject.Values[AName].Clone);

2. Fehlende Typüberprüfung in `CheckIDValue`:
- **Problem**: `AJSONObject.Values[AName].AsType<String>` setzt voraus, dass der Wert ein String ist. Bei anderen Typen (Zahl, Boolesch) kommt es zu einer Exception.
- **Lösung**: Prüfung des Werttyps vor der Konvertierung:


Delphi-Quellcode:
   var
     LValue: TJSONValue;
   begin
     LValue := AJSONObject.Values[AName];
     if LValue is TJSONString then
       LIDValue := TJSONString(LValue).Value
     else
       raise Exception.Create('Unexpected type for ' + AName);

3. Irreführender Kommentar in CheckXDataRef:

Problem: Der Kommentar deutet an, dass AJSONObject nach RemovePair(...).Free ungültig sei, was nicht zutrifft. Das Objekt bleibt gültig, aber der Wert des neuen Paars ist betroffen (siehe Punkt 1).

4. Potenzielle Ausnahmen bei fehlenden Feldern:

Problem: Wenn ein Feld mit @-Präfix in AInsertArr/AFieldArr angegeben wird, das ursprüngliche Feld (LFeldname ohne @) aber nicht existiert, wird CheckXDataRef das @ref-Feld nicht anlegen, was zur Exception führt. Dies könnte eine falsche Annahme über die Datenintegrität sein.

### Zusammenfassung
Die kritischsten Fehler sind die **ungültige Referenz** in `CheckXDataRef` und die **fehlende Typüberprüfung** in `CheckIDValue`. Diese müssen korrigiert werden, um Speicherzugriffsfehler (Access Violations) und unerwartete Exceptions zu vermeiden.
  Mit Zitat antworten Zitat
Benutzerbild von t2000
t2000

Registriert seit: 15. Dez 2005
Ort: NRW
247 Beiträge
 
Delphi 12 Athens
 
#8

AW: Memoryleak oder fatale Exception bei TJSONObject.RemovePair

  Alt 10. Mär 2025, 10:45
Gute Prüfung. Aber wie man an eigenen "raise" Aufrufen sehen kann, ist das Fehler/Exception Handling außerhalb. Und da werden auch eventuelle Typenfehler der Übergabe ausgewertet.
Leider machen alle KI Modelle per default sehr sehr viele Annahmen zur Fehlerbehandlung. Und in vielen Fällen kann dort erheblich Code gespart werden. Aber besser so, als anders herum.
Thomas
(Wir suchen eine(n) Entwickler(in) mit Ambitionen später ggf. die Softwarefirma zu leiten)
Aktuell nicht mehr. Aber ab vielleicht 2024/2025 wird das wieder sehr interessant!
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 10:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz