AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Fehler beim Programm beenden
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler beim Programm beenden

Ein Thema von Jens Hartmann · begonnen am 19. Okt 2015 · letzter Beitrag vom 15. Nov 2015
Antwort Antwort
TiGü
Online

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

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 09:30
//Jetzt lade ich die Kundendaten aus der DB und lasse das ganze durch eine for-Schleife laufen
Dir ist schon bewusst, das du an dieser Stelle immer wieder ein neues Objekt erzeugst, aber nur die letzte Instanz davon im FormDestroy freigibst?

Beispiel: Wenn du 10 Kunden erzeugst TMyKunden_Daten := TOCustomers.Create; , gibst du im FormDestroy nur Nummer 9 frei.
Die Kunden 0 bis 8 hängen noch im Speicher rum und das sind deine Speicherlecks.

Verwalte doch diese Instanzen von Kunden, Systemen und Gebäuden in seperaten Objektlisten.
Bei Freigabe der Objektlisten werden dann auch die darin gespeicherten Instanzen freigeben.

Beispiel:
Delphi-Quellcode:
var
  I, J, K: Integer;
  CustomerNode, BuildingNode, SystemNode: PVirtualNode;
  LCustomer: TOCustomers;
begin
  VstKunden.BeginUpdate;
  try
    VstKunden.Clear;

    CustomerNode := VstKunden.AddChild(nil);
    VstKunden.InvalidateNode(CustomerNode);
    VstKunden.NodeDataSize := SizeOf(TCustomersData);
    { Hier glaube ich liegt das erste Problem. Ich setze NodeDataSize auf TCustomersData.
      Was aber ist mit TBuildingData und TSystemData? Benötige ich die nicht,
      weil es nur um den ersten Node geht? }


    FCustomers := TObjectList.Create;
    // Jetzt lade ich die Kundendaten aus der DB und lasse das ganze durch eine for-Schleife laufen
    for I := 0 to 10 do
    begin
      LCustomer := TOCustomers.Create;
      FCustomers.Add(LCustomer);

      LCustomer.Kunden_Kundenname := 'Hallo';
      LCustomer.Ansprechpartner_Position := 'Hallo';
      LCustomer.Ansprechpartner_Telefon1 := 'Hallo';

      // Inerhalb der Schleife folgen dann die tieferen Datenpunkte
      BuildingNode := AddVSTCustomer(VstKunden, CustomerNode, LCustomer);

      // Objektedaten laden aus Objektdatenbank
      // Systemdaten
      // Menüpunkte
    end;

    // ExpandedRootNodes(VstKunden);
    VstKunden.SortTree(0, SdAscending, True);
  finally
    VstKunden.EndUpdate;
  end;
end;
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
734 Beiträge
 
Delphi 12 Athens
 
#2

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 09:40
Ergänzung:

Das OnFreeNode des VST brauchst du dann nicht mehr, da du die Freigabe selbst machst.

Ist doch auch irgendwie logischer: Du erzeugst die Objekte, übergibst sie dem VST zur Anzeige, und zerstörst sie selbst wieder.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 10:13
Du benutzt den VST (meiner Meinung nach) recht .. ungewöhnlich Ich schaue später daheim nochmal genauer drüber und poste ein paar Verbesserungsvorschläge.

Edit:
Also, ich bin immer sehr gut damit gefahren, wenn ich einen einzigen Record-Typ für alle Nodes verwendet habe. Das ist auch die einzig valide Anwendungsweise. In deinem Falle hast du nur "Glück", dass deine Records alle gleich groß sind.

Wenn ich verschiedene Node Typen habe, mache ich das immer so:
Delphi-Quellcode:
type
  TNodeType = (ntCustomer, ntBulding, ..);

  PNodeData = ^TNodeData;
  TNodeData = record
    NodeType: TNodeType;
    NodeObject: TObject;
  end;
Deine Methode über das NodeLevel zu differenzieren geht natürlich auch.

Die NodeDataSize ist aber in jedem Falle immer SizeOf(TNodeData) für alle Nodes.

Bezüglich der Objektverwaltung sehe ich zwei Möglichkeiten:
  1. Du behälst die einzelnen Objekte in einer gemeinsamen Liste (jeweils eine für Kunden, Gebäude, etc) und gibst dem NodeData Record jeweils nur einen Zeiger auf das Objekt mit. Die Freigabe der Objekte erfolgt dann gemeinsam beim Freigeben der Liste (Achtung: Je nachdem musst du manuell iterieren und Free aufrufen.
    Diese Methode trennt ganz gut Daten von der Anzeige, allerdings hast du ein Problem, wenn zur Laufzeit dynamisch Einträge aus der Liste gelöscht oder hinzugefügt werden sollen, bzw. musst du dann doppelten Aufwand betreiben.
  2. Die zweite Möglichkeit wäre deshalb beim Hinzufügen der Nodes deine Objekte mit Create zu konstruieren und den Zeiger wieder entsprechend zuzuweisen. Dann implementierst du noch das OnFreeNode Event und rufst darin NodeData^.NodeObject.Free auf.
    Beim Löschen einer Node wird dann automatisch auch das Objekt freigegeben.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (23. Okt 2015 um 11:31 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 19:27
EDIT: Videos doch gefunden...

Erstmal vielen Dank für die Tips. Ich werde das ganz jetzt mal durcharbeiten und versuchen zu verbessern. Ich werden das dann hier nochmal einstellen.

PS: Kann man irgendwo noch auf das "Stammtisch" Video zum VST zugreifen?

Gruß Jens
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.

Geändert von Jens Hartmann (23. Okt 2015 um 19:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 20:09
Groß gesagt gefunden und dann war es doch nur das vom Stammtisch 1...

Weiß jemand wo das Video vom Stammtisch 2 zu finden ist?
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#6

AW: Fehler beim Programm beenden

  Alt 24. Okt 2015, 18:50
Hallo nochmal,

ich glaube das ich bei der Definition der Datenhaltung (Objekt, Record) schon was verbessern muss. Eventuell kann mit hier jemand einen Tip geben...

Aktuell habe ich 3 Klassen "Kunde", "Objekt" und "System"

Der Aufbau sieht wie folgt aus:

Delphi-Quellcode:
{ TObject für die Kundendaten }
type
  TOCustomers = class(TObject)
    private
      FID : integer; //ID
      FESID : integer; //ESID
      FName : string; //Name des Kunden
      FOrt : string; //Ort des Kunden
      FStraße : string; //Straße des Kunden
      FAnsprechpartnerId : integer; //Ansprechpartnernummer
      FAnsprechpartner : string; //Ansprechpartner
      FAnsPosition : string; //Position/Stellung
      FEMail : string; //EMail des Ansprechpartners
      FTel1 : string; //Telefonnummer 1 des Ansprechpartners
      FTel2 : string; //Telefonnummer 2 des Ansprechpartners
      FFax : string; //Faxnummer des Ansprechpartners
      FBemerkung : string; //Kunden Zusatzinformation
    public
      property Kunden_Kundennummer : integer read FID write FID;
      property Kunden_ESKundennummer : integer read FESID write FESID;
      property Kunden_Kundenname : string read FName write FName;
      property Kunden_Ort : string read FOrt write FOrt;
      property Kunden_Straße : string read FStraße write FStraße;
      property Kunden_Bemerkung : string read FBemerkung write FBemerkung;
      property Ansprechpartner_Id : integer read FAnsprechpartnerId write FAnsprechpartnerId;
      property Ansprechpartner_Name : string read FAnsprechpartner write FAnsprechpartner;
      property Ansprechpartner_Position : string read FAnsPosition write FAnsPosition;
      property Ansprechpartner_EMail : string read FEMail write FEMail;
      property Ansprechpartner_Telefon1 : string read FTel1 write FTel1;
      property Ansprechpartner_Telefon2 : string read FTel2 write FTel2;
      property Ansprechpartner_Fax : string read FFax write FFax;
  end;

//Das Object für die Objektdaten und Systemdaten ist ähnlich. Teilweise andere Felder
Den Bezug zum VST stelle ich über das NodeLevel her.

Delphi-Quellcode:
  NodeLevel 0 = Datenbankpfad
  NodeLevel 1 = Kundendaten
  NodeLevel 2 = Objektdaten
  NodeLevel 3 = Systemdaten
  NodeLevel 4 = Menüpunkte zum System
Beim Click auf den jeweiligen Knoten (VST in Baumstruktur auf der Linken Programmseite), werden auf der rechten Seite in verschiedenen Frames die zugehörigen Datenangezeigt und zum editieren etc. zur Verfügung gestellt.

Da ich drei Objekte habe, stellt sich mir die Frage erneut nach dem NodeDataSize . Wie geh man sowas an.

Vorstellen könnte ich mir folgende alternativen.

1.

Das Object "TOCustomers" bekommt ein Feld Objektdaten array of TOBuildings und das Object TOBulidings bekommt ein Feld Systemdaten array of TOSystems 2.

Die Objecte liegen ja je in einer eigenen Unit. Diese könnte man ja eventuell in einen Record einbinden:

Delphi-Quellcode:
type
  TRKundenDaten = record
    FKundedaten : TOCustomers;
    FObjektdaten : TOBuildings;
    FSystemdaten : TOSystems;
  end;

  PRKundenDaten = ^TRKundenDaten;
Vieleicht gibt es ja noch bessere/sinnvollere Wege. Die Variante 2 scheint mir aktuell am sinnvollsten. Dabei würde ich einen Record verwenden, welchen ich dann auch dem NodeDataSize zuweisen könnte.

vst.NodeDataSize:=sizeof(TRKundenDaten); Weiterhin, wäre dann das OnFreeNode klar...

Delphi-Quellcode:
procedure TForm1.vstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  daten: PRMeineDaten;
begin
  daten := vst.GetNodeData(node);
  daten^.FKundendaten.free;
  daten^.FObjektdaten.free;
  daten^.FSystemdaten.free;
end;
Ich hoffe, das ich nicht ganz auf dem Holzweg bin...
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
TiGü
Online

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

AW: Fehler beim Programm beenden

  Alt 26. Okt 2015, 08:38
Eventuell kann mit hier jemand einen Tip geben...
Schaue dir den editierten Post von Zacherl an:
http://www.delphipraxis.net/1319525-post21.html

Wahrscheinlich hast du übersehen, das er ihn erweitert hat.
Da steht alles drin, was du wissen musst.
Punkt Nummer eins habe ich dir bspw. schon auf der vorigen Threadseite gezeigt.
Du musst die Vorschläge nur verstehen und umsetzen.
  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 13:28 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