AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi OnResize => AV, Wenn OnResize leer...
Thema durchsuchen
Ansicht
Themen-Optionen

OnResize => AV, Wenn OnResize leer...

Ein Thema von glkgereon · begonnen am 29. Mai 2006 · letzter Beitrag vom 3. Jun 2006
Antwort Antwort
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#1

OnResize => AV, Wenn OnResize leer...

  Alt 29. Mai 2006, 17:43
Hi,

Ich habe ein sehr komisches Problem...

Ich habe ein Formular, in dem sich einige übliche Kompos befinden. (Genauer: TRadioGroup, TGroupBox, TButton, TJvDirectoryEdit, TJvFileNameEdit, TLabel, TProgressBar, TJvRichEdit, TRichEdit, TTimer, TPopupMenu, TJvTrayIcon).

Auf einmal (Ich habe keine Kompo geändert, hinzufügt oder gelöscht) wirft er beim Ändern der Fenstergröße eine Exception.
Zitat:
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt G:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Borland Studio-Projekte\VPlan\VPlan.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x0040d971: write of address 0x00030fe8'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
Aber auch das nur unter bestimmten Umständen:
Das Programm analysiert ein paar dateien und lädt dann die daten hoch...die AV kommt erst nachdem dies getan wurde!
zudem kann man sie ebenfalls verhindern indem man im OnResize zB ein ShowMessage('Resizing...') einfügt...

für mich absolut unerklärbar.
Das einzige was während diesem Analysieren einfluss auf TForm_Main (Forumlar) einfluss nimmt, sind folgende Sachen:

Delphi-Quellcode:
procedure TForm_Main.ColorLog(ID, Len: Integer; Col: TColor);
//bestimmten Teil im Log färben
begin
  Rch_Log.SelStart:=ID;
  Rch_Log.SelLength:=Len;
  Rch_Log.SelAttributes.Color:=Col;
  Rch_Log.SelLength:=0;
end;

procedure TForm_Main.Log(Value, Msg, Level: String; Typ: TLogLevel);
//Ereignis in Log ablegen und färben
var S, Datum: String;
begin
  if FLogLevel>Typ then Exit;
  Datum:=DateTimeToStr(Now);
  if Level<>'then Level:='['+Level+'] ';
  S:=Datum + DSep + Level + Value + VSep + cLogTypes[Typ].Desc + ' (' + Msg + ')';

  Rch_Log.Perform(WM_VSCROLL, SB_BOTTOM,0);
  Rch_Log.Refresh;
end;

procedure TForm_Main.InitProgress(Max: Integer; Action: String);
begin //Progressbar Initialisieren
  Prg_Progress.Max:=Max;
  Prg_Progress.Min:=0;
  Prg_Progress.Step:=1;
  Lbl_Status.Caption:=Action;
  Lbl_Status.Refresh;
  FLastAkt:=Now;
end;

procedure TForm_Main.SetProgress(Progress: Integer = -1);
begin //Progressbar weitersetzen
  if Progress=-1 then
    Prg_Progress.StepIt
  else
    Prg_Progress.Position:=Progress;
  Prg_Progress.Refresh;
  if MillisecondsBetween(FLastAkt,Now)>1000 then Application.ProcessMessages;
end;

procedure TForm_Main.UnInitProgress;
begin //Progressbar zurücksetzen
  Prg_Progress.Position:=0;
  Lbl_Status.Caption:='Bereit';
end;
Mir ist das verhalten absolut unerklärlich, ich hoffe irgendwer kann mir wenigstens sagen wo ich anfangen könnte nach einem fehler zu suchen
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#2

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 12:25
Weiss das echt keiner?

Es ist echt relativ wichtig :-/
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 12:39
das ganze wird nix mit dem Onresize direkt zu tun haben sondern ist eine Folgeerscheinung. Du zerhaust irgendwo schon eher den Speicher. Und je nach dem was du anschließend machst bzw. ob was im OnResize steht verschiebt sich der Speicher. Und davon hängt es dann ab ob du das Glück hast das du die AV bekommst.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#4

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 12:41
Zitat von SirThornberry:
das ganze wird nix mit dem Onresize direkt zu tun haben sondern ist eine Folgeerscheinung. Du zerhaust irgendwo schon eher den Speicher. Und je nach dem was du anschließend machst bzw. ob was im OnResize steht verschiebt sich der Speicher. Und davon hängt es dann ab ob du das Glück hast das du die AV bekommst.
Also ich vermute das es mit einer Kompo zu tun hat. mein Eigener Code läuft definitiv ohne AV durch.

Ich habe atm das TJvFileNameEdit bzw TJvDirectoryEdit im Verdacht.

was kann man da ausprobieren?

Edit:
Wobei auffällig ist das es erst auftritt wenn ich einmal meinen Code ausgeführt hab...
ließe ja eigentlich darauf schließen das ich in speicherbereichen rumfummel wo ich nix zu suchen hab....
ich checke mal meinen code...
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 13:01
das klingt wirklich so als ob du mit deinem Code irgendwo in falschen Speicherbereichen rumfummelst. Prüf am besten mal ob du Eventuell über Arraygrenzen hinaus gehst (0 basierend nicht beachtet), einen String aus einem Stream ausliest/scheibst mit
Stream.Read(DeinString, Len); anstelle von
Stream.Read(DeinString[1], Len); (vielleicht auch vorher setlength vergessen), etc.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#6

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 13:12
Zitat von SirThornberry:
das klingt wirklich so als ob du mit deinem Code irgendwo in falschen Speicherbereichen rumfummelst. Prüf am besten mal ob du Eventuell über Arraygrenzen hinaus gehst (0 basierend nicht beachtet), einen String aus einem Stream ausliest/scheibst mit
Stream.Read(DeinString, Len); anstelle von
Stream.Read(DeinString[1], Len); (vielleicht auch vorher setlength vergessen), etc.
Ha!!!

Ich habe einfach mal eine Importer-Klasse auskommentiert, und siehe da: es funkt.
Das heisst zwar immer noch nicht das ich den Fehler hab, aber die möglicherweise fehlerhaften Zeile reduzieren sich von mehreren Tausend auf gut 100

woran könnte es hier liegen?
Delphi-Quellcode:
TImport_Virtual = class(TObject)
  private //Basisklasse für ImportTyp
    FFileName: String;
    FFileExt: String;
    FMaxAge: TDateTime;
    FHasData: Boolean;
  public
    FData: TData;
    constructor Create; virtual; abstract;
    destructor Destroy; virtual; abstract;
    function OpenFile(var Err: String):Boolean; virtual; abstract;
    function CloseFile(var Err: String):Boolean; virtual; abstract;
    function Analyse(var Err: String):Boolean; virtual; abstract;
    function GetData(var Dat: TData):Boolean;
    property FileName: String read FFileName write FFileName;
    property MaxAge: TDateTime read FMaxAge write FMaxAge;
    property HasData: Boolean read FHasData write FHasData;
  end;

TMTTImport = class(TImport_Virtual)
  private //Import aus MTT-Datei
    S: TStringList;
    Datum: TDateTime;
  public
    constructor Create; override;
    destructor Destroy; override;
    function OpenFile(var Err: String):Boolean; override;
    function CloseFile(var Err: String):Boolean; override;
    function Analyse(var Err: String):Boolean; override;
  end;



constructor TMTTImport.Create;
begin
  inherited;
  FFileExt:='.mtt';
  FHasData:=True;
  S:=TStringList.Create;
end;

destructor TMTTImport.Destroy;
begin
  S.Free;
  inherited;
end;

function TMTTImport.OpenFile(var Err: String):Boolean;
var M,D: String;
    Y: Integer;
begin
  try
    Result:=True;
    if FileExists(FFileName) then
      if LowerCase(ExtractFileExt(FFileName))=LowerCase(FFileExt) then
        begin
        Result:=False;
        Err:='';
        S.LoadFromFile(FFileName);
        M:=ExtractFileName(FFileName);
        M:=Copy(M,1,Pos('.',M)-1);
        M:=Copy(M,Pos('-',M)+1);
        D:=ExtractFileName(FFileName);
        D:=Copy(D,1,Pos('-',D)-1);
        D:=Copy(D,Pos('X',D)+1);
        Y:=YearOf(Date);
        Datum:=EncodeDate(Y,StrToInt(M),StrToInt(D));
        if Datum>Now+FMaxAge then Datum:=EncodeDate(Y-1,StrToInt(M),StrToInt(D));
        S.Clear;
        end
      else
        Err:=cEFileExt
    else
      Err:=cEFileExists;
  except
    Result:=True;
    Err:=cEUnknown;
  end;
end;

function TMTTImport.CloseFile(var Err: String):Boolean;
begin
  S.Clear;
  Result:=False;
end;

function TMTTImport.Analyse(var Err: String):Boolean;
var Data: TStringDynArray;
    i:Integer;
begin
  try
    Data:=Explode(#$0D+#$0A+#$0D+#$0A,S.Text);
    SetLength(FData.MTData,Length(Data));
    for i:=0 to Length(Data)-1 do
      begin
      FData.MTData[i].Value:=Data[i];
      FData.MTData[i].Datum:=Datum;
      end;
    SetLength(Data,0);
    Result:=False;
  except
    Result:=True;
  end;
end;
PS: die TMTTImport ist nicht die einzige die von TImport_Virtual abgeleitet ist, aber die einzige die den Error fabriziert...
von daher sollten das eigentlich alle relevanten code-teile sein.

PS2: Könnte event daran liegen?
Denn TMTTImport ist die einzige klasse die was in FData.MTData reintut....
Delphi-Quellcode:
type
  TVTData = record //Datensatz
    Stunde: String;
    Fehlend: String;
    Vertretend: String;
    Klasse: String;
    Fach: String;
    Raum: String;
    BemerkungS: String;
    BemerkungL: String;
    Datum: String;
  end;
  TVTDataArray = array of TVTData;

  TMTData = record
    Datum: TDateTime;
    Value: String;
  end;
  TMTDataArray = array of TMTData;

  TData = record
    VTData: TVTDataArray;
    MTData: TMTDataArray;
  end;

var FData: TData;

function TImport_Virtual.GetData(var Dat: TData):Boolean;
begin
  try
    Move(FData,Dat,SizeOf(FData));
    Result:=False;
  except
    Result:=True;
  end;
end;
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 13:35
ich vermute den Fehler hier:
Delphi-Quellcode:
  try
    Move(FData,Dat,SizeOf(FData));
    Result:=False;
  except
    Result:=True;
  end;
Dat und fData beinhalten dynamiche Arrays. Dynamische Arrays sind aber auch nur Pointer. Durch das Move lässt du die Arrays beider Records auf das gleiche zeigen. Wenn dann der erste Record frei gegeben wird würde der zweite ins nirvana zeigen (Vermutung nach erstem überfliegen des Ganzen)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#8

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 13:35
Zitat von SirThornberry:
ich vermute den Fehler hier:
Delphi-Quellcode:
  try
    Move(FData,Dat,SizeOf(FData));
    Result:=False;
  except
    Result:=True;
  end;
Dat und fData beinhalten dynamiche Arrays. Dynamische Arrays sind aber auch nur Pointer. Durch das Move lässt du die Arrays beider Records auf das gleiche zeigen. Wenn dann der erste Record frei gegeben wird würde der zweite ins nirvana zeigen (Vermutung nach erstem überfliegen des Ganzen)
Genau das vermute ich auch^^
wie würde ich das denn sauber und funktionierend schreiben?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#9

Re: OnResize => AV, Wenn OnResize leer...

  Alt 3. Jun 2006, 14:23
Delphi-Quellcode:
try
  Dat.VTData:= Copy(FData.VTData);
  Dat.MTData:= Copy(FData.MTData);
  Result:= false;
except
  Result:= true;
end;
So zum Beispiel
  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 11:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz