Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi AccessViolation bei TLabel.Create(nil) (https://www.delphipraxis.net/139285-accessviolation-bei-tlabel-create-nil.html)

diComm 26. Aug 2009 07:48


AccessViolation bei TLabel.Create(nil)
 
Hallo

Vornweg, ich arbeite mit Delphi 2007 auf Windows XP.

Ich habe einen ziemlich eigenartigen Fehler und komme nicht weiter.
Ich fülle eine TScrollBox zur Laufzeit mit TPanels auf denen je 6 TLabels sind. Dies hat vor kurzem wunderbar geklappt (die letzten ca 3 Jahre...) doch seit einer Weile erhalte ich eine AccessViolation beim erstellen eines Labels.

Das intressante ist, es ist nicht immer dasselbe Label und bis jetzt nie schon beim ersten. Der Fehler kommt zB beim zweiten Label auf dem dritten Panel.

Ich habe es schon mit verschiedenen Owner probiert (nil, Self, das Panel, Application), habe diverse Application.ProcessMessages verteilt (hat den Fehler etwas nach hinten geschoben, aber nicht behoben...) und habe verschiedene Workarounds Probiert (DuplicateComponents aus der Unit uClone, ebenfalls seit Jahren erfolgreich im Einsatz, bei mir gibts jetzt aber einen Hänger, steht komplett still...)

Hat jemand schon mal sowas erlebt? Ich kann mir schonmal nicht vorstellen, wie ein TLabel.Create(nil) eine AccessViolation hervorruft...

Danke schonmal
Gruss
Tom

Blup 26. Aug 2009 08:18

Re: AccessViolation bei TLabel.Create(nil)
 
Das hört sich an, als wenn der Speichermanager an anderer Stelle zerschossen wurde.

Owner der Steuerelemente ist üblicherweise das Formular.

diComm 26. Aug 2009 08:33

Re: AccessViolation bei TLabel.Create(nil)
 
In meiner verzweiflung habe ich es mit verschiednen Owner probiert, das war das einzige wo ich mir eine accessViolation vorstellen konnte...

Wie könnte ich das mit dem Speichermanager prüfen? alles andere funktioniert, andere Forms, die über den Designer gestaltet sind und nicht mit eigenen Creates funktionieren ohne ersichtliche Fehler.

Blup 26. Aug 2009 09:58

Re: AccessViolation bei TLabel.Create(nil)
 
Leider gibt es dafür keine einfache Lösung, da hilft nur sauber zu Programmieren.
Beliebte Ursachen:
- Zugriffe über Arraygrenzen hinaus
- Pointer auf Arrayelemente und Änderung der Arraygröße
- Pointer auf Elemente die bereits freigegeben wurden
- Objektvariablen die auf Objekte verweisen die freigegeben wurden (insbesondere Elemente von TObjectList)

mkinzler 26. Aug 2009 10:02

Re: AccessViolation bei TLabel.Create(nil)
 
Etwas Code würde die Fehleranalyse ungemein vereinfachen :zwinker:

diComm 26. Aug 2009 10:14

Re: AccessViolation bei TLabel.Create(nil)
 
hmm... kann eigentlich alle 4 Punkte mit ziemlicher Sicherheit ausschliessen.
Würde dann der Fehler nicht sowieso beim Zugriff auf das nichtvorhandene Objekt auftreten?
Der Fehler kommt eben leider genau auf dem Create eines Labels, und dass, nachdem der Befehl vorher schon ein paarmal funktioniert hat in einer Schleife, wo auch alle andern Befehele vorher schon mehrmals ohne Fehler durchlaufen...

Aber danke trotzdem


Hier der Code

Delphi-Quellcode:
function TLohnartsForm.PushPanel(AScrollBox : TScrollBox): TPanel;

  function getNewPanel(aParent : TScrollBox) : TPanel;
  var
    i : integer;
    aLabel : TLabel;
  begin
    Result := TPanel.Create(nil);
    With Result Do
    Begin
      Name := Format('Panel_%s_%d',[AScrollBox.Name,AScrollBox.ControlCount]);
      Caption := '';
      Parent := Self;
      Left := 8;
      Top := 312;
      Width := 425;
      Height := 25;
      TabOrder := 2;
      Visible := False;
    End; { With }
    For i := 0 To 5 Do
    Begin
      Try
        aLabel := TLabel.Create(Result);
      Except
        Break;
      End;

      With aLabel Do
      Begin
        Name := Format('Label_%s_%d_%d',[AScrollBox.Name,AScrollBox.ControlCount,i]);
        Left := getLeft(i);
        Top := 6;
        Width := 44;
        Height := 13;
        Parent := Result;
        If AScrollBox.ControlCount = 0 Then
        Begin
          Caption := getCaption(i);
          Font.Charset := DEFAULT_CHARSET;
          Font.Color := clWindowText;
          Font.Height := -11;
          Font.Name := 'Tahoma';
          Font.Style := [fsBold];
          ParentFont := False;
        End
        Else
        Begin
          Caption := '---';
        End; { If }
      End; { With }
    End; { For }
  end;

var
  I : Integer;
begin
  //Application.ProcessMessages;
  Result := getNewPanel(AScrollBox);

  With Result Do
  Begin
    Parent := AScrollBox;
    Height := Item_Height;
    Top := AScrollBox.ControlCount * Height;
    Align := alTop;
    Visible := True;
    ParentBackground := False;

    For I := 0 To Pred(ControlCount) Do
    Begin
      With Controls[I] Do
      Begin
        Top := (Result.Height - Controls[I].Height) Div 2;
        AutoSize := False;
        If I = 0 Then
        Begin
          Width := AScrollBox.ClientWidth - (5 *
            (Item_Text_Width + Item_Margin)) - (Item_Margin * 3);
          Anchors := [akTop,akLeft,akRight];
          Left := Item_Margin;
        End
        Else
        Begin
          Left := ((AScrollBox.ClientWidth - Item_Margin) -
            ((ControlCount - I) * (Item_Text_Width + Item_Margin)));
          Width := Item_Text_Width;
          Anchors := [akTop,akRight];
        End; { Else }
      End; { With }
    End; { For }
  End; { With }
end;
Die Methode wird in eriner Schleife aufgerufen.
Der Fehler tritt in der Zeile aLabel := TLabel.Create(Result); auf, allerdings nicht im ersten durchgeng der For schleife... und auch nciht, wenn ich die ganze Methode das erste mal aufrufe, erst im dritten mal.

mkinzler 26. Aug 2009 10:16

Re: AccessViolation bei TLabel.Create(nil)
 
Die geschachtelten withs sind m.E. sehr gefährlich

Muetze1 26. Aug 2009 10:19

Re: AccessViolation bei TLabel.Create(nil)
 
Wie räumst du die Elemente wieder ab? Gibst du neben den Panels auch die darauf enthaltenen Labels einzeln frei?

diComm 26. Aug 2009 10:27

Re: AccessViolation bei TLabel.Create(nil)
 
Habs mal ohne die Geschlachteleten Withs probiert... selber Fehler, daran liegts nicht

Die Panels lösche ich so

Delphi-Quellcode:
procedure TLohnartsForm.DeletePanels(AScrollBox : TScrollBox);
begin
  While AScrollBox.ControlCount > 0 Do
  Begin
    AScrollBox.RemoveControl(AScrollBox.Controls[AScrollBox.ControlCount-1]);
  End; { While }
end;
Ich habs aich mit .Free probiert, aber eben, der Fehler kommt bevor ich diese Zeilen ausführen kann.

Die Labels räume ich nicht separat ab. Da ich als Owner den Panel habe, denke ich, das es ohne gehen sollte... aber soweit komme ich ja gar nicht.

hoika 26. Aug 2009 10:35

Re: AccessViolation bei TLabel.Create(nil)
 
Hallo,

ich würde erst mal das Result durch eine lokale Variable ersetzen,
und dann, du musst du leider durch

- alles auskommentieren, bis der Fehler nicht mehr kommt
vor allem auch nachfolgenden Code (For I := 0 To Pred(ControlCount) Do )
- schrittweise wieder reinnehmen
testen, testen ...


Heiko

diComm 26. Aug 2009 10:47

Re: AccessViolation bei TLabel.Create(nil)
 
Naja, habe schon gut 3 Tage mit Auskommentieren und Probieren verbracht... auch besonders an erwähnter Stelle... leider ohne Erfolg.

Hatte die leise Hoffnung, dass sich jemand meldet mit dem Satz :"ja dass kenne ich, da muss man nur..." :-)

Ich hab mir mal FastMM4 runtergeladen und schaue mal, ob ich sonstwo eine Speuicherverletzung habe die dann zu dem Problem führt...

Mal ein herzliches "Zwischendanke" für alle Ideen bis jetzt

hoika 26. Aug 2009 11:13

Re: AccessViolation bei TLabel.Create(nil)
 
Hallo,

dann mache es doch mal anders rum.
Neues Projekt, und deinen Code schrittweise rein in das einzige Form.

BTW: Neue IDE-Komponenten installiert ?


Heiko

diComm 26. Aug 2009 12:08

Re: AccessViolation bei TLabel.Create(nil)
 
Ich glaub ich spinne...

FastMM4 runtergeladen und ins Uses der .dpr eingebunden -> keine änderung, weiterhin ein Fehler

FastMM_FullDebugMode.dll kompiliert und in FastMM4Options.inc FullDebugMode eingeschaltet, um an den Fehler zu kommen -> Programm läuft ohne Fehler durch den Code.

Ich bin mir gerade nicht so sicher, ob ich mich freuen oder ob ich gefrustet laut schreiend ein paar Topfpflanzen über den Balkon rauswerfen soll.

Trotzdem zur ergänzung:
Ich habe GExperts installiert und diverse Komponenten, darunter Python4Delphi, die jvcl, Synedits und ein paar Selbstgemachte...

hoika 26. Aug 2009 13:56

Re: AccessViolation bei TLabel.Create(nil)
 
Hallo,

also das mit den Pflanzen is ne gute Idee ;)

Ich meinte, ob du da irgendwa Komponenten neu instaliiert/geupdatet hast.

Auf jeden Fall ist es ein böser Fehler,
das solltest ohne FullDebug auf jeden Fall den Fehler suchen.


Heiko

diComm 26. Aug 2009 14:08

Re: AccessViolation bei TLabel.Create(nil)
 
Hallo

nein, habe nichts geupdated oder neuinstalliert.

Ja, schon nur weil der Fehler ja einfach nicht mehr da ist und nicht wirklich behoben ist werde ich noch weitersuchen...
aber ich habe noch ein paar Baustellen die nicht mit diesem Fehler zu tun haben... ich nehme mich für eine Weile diesen an und komme später auf meine AcessViolation zurück. Der Tipp mit dem neuen Projekt ist auf jedenfall mal gut. Ich bin mir zwar fast sicher dass dann der Fehler auch nicht kommt, aber da ich schon fast alles Andere probiert habe, werde ich es trotzdem machen.

Werde hier dann auch weiterschreiben wenn ich den Fall der Mysteriösen AccessViolation gelöst habe und bin natürlich weiterhin froh um ein paar Ideen.

Danke nochmals an alle

Blup 28. Aug 2009 09:06

Re: AccessViolation bei TLabel.Create(nil)
 
Die Ursache wird vermutlich nicht innerhalb der Methode PushPanel liegen.
Dort werden nur neue Steuerelemente erzeugt, die Fehlerursache ist eher da zu suchen, wo etwas freigegeben wird.
Das kann ein ganz anderes Formular/Klasse sein.

RemoveControl löscht das Steuerelement nicht, sondern entfernt es nur aus der Liste der untergeordnet anzuzeigenden Elemente.
Das Steuerlement bleibt dann noch so lange im Speicher vorhanden, bis auch der Owner freigegeben wird.

diComm 1. Sep 2009 16:27

Re: AccessViolation bei TLabel.Create(nil)
 
Hallo Blup

Sorry, habe etwas lange nicht vorbeigeschaut...

Ja, das dachte ich auch und habe speziell darauf geachtet. Allerdings kommt vom Starten der Applikation bis zum Fehler, der ja bei einem Create ist, kein Free, Release, RemoveControl etc vor, das käme erst danach.

Bin noch nicht dazu gekommen weiter bei diesem Fehler zu suchen, muss erst ein paar andere Baustellen schliessen damit das ganze für die Funktionstest zu meinen Betatesterchen kann. Werde vermutlich nicht drumrum kommen, den ganzen Source in ein anderes Projekt Schritt für Schritt reinzukopieren...

Danke trotzdem

Gruss
Tom


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:47 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