Einzelnen Beitrag anzeigen

Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#31

Re: Clear von TList überschreiben mit Objekten

  Alt 3. Jul 2007, 16:08
So, ich habs:
Code:
FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.

Freed object class: TImageEnVect

Virtual method: Offset +136

Virtual method address: 4E9078

The allocation number was: 71947

Stack trace of when the object was allocated (return addresses):
402FDE [System][@GetMem]
404453 [System][TObject.NewInstance]
40481A [System][@ClassCreate]
5BB985 [ievect][TImageEnVect.Create]
4227E9 [FastMM4][TList.SetCapacity]
422650 [FastMM4][TList.Grow]
5FCCB4 [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.Add][148]
5FCD37 [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.Assign][171]
6078DF [units\FotoBook\Units\FotoBook.pas][FotoBook][TFotoBook.Display][1227]
6515DE [formulare\frmMain.pas][frmMain][TMain.lbPageListClick][376]

Stack trace of when the object was subsequently freed (return addresses):
404471 [System][TObject.FreeInstance]
404865 [System][@ClassDestroy]
5BC186 [ievect][TImageEnVect.Destroy]
4044B7 [System][TObject.Free]
5FD0DC [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.Clear][230]
6078D4 [units\FotoBook\Units\FotoBook.pas][FotoBook][TFotoBook.Display][1226]
6515DE [formulare\frmMain.pas][frmMain][TMain.lbPageListClick][376]
46070A [Controls][TControl.Click]
44734A [StdCtrls][TCustomListBox.CNCommand]
460202 [Controls][TControl.WndProc]

The current stack trace leading to this error (return addresses):
5FD441 [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.RescalePage][400]
5FCCB4 [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.Add][148]
5FD287 [units\FotoBook\Units\PageCollection.pas][PageCollection][TPageCollection.UpdatePage][347]
607906 [units\FotoBook\Units\FotoBook.pas][FotoBook][TFotoBook.Display][1235]
6515DE [formulare\frmMain.pas][frmMain][TMain.lbPageListClick][376]
46070A [Controls][TControl.Click]
44734A [StdCtrls][TCustomListBox.CNCommand]
460202 [Controls][TControl.WndProc]
7E36C665 [CallWindowProcW]
4B763D [TntControls.pas][TntControls][TWinControlTrap.DefWin32Proc][604]
Der zugehörige Quellcode:
Delphi-Quellcode:
TempPageCollection.Clear;
  TempPageCollection.Assign(PageCollection);
  
  // nur im Entwurfsmodus speichern
  if (DisplayMode = dmDesign) then
  begin
    // Seiten sichern und in Liste aktualisieren
    if Assigned(LeftPage) then
    begin
      PageCollection.UpdatePage(LeftPage);
    end;
    if Assigned(RightPage) then
    begin
      PageCollection.UpdatePage(RightPage);
    end;
  end;
Aber ich verstehe eins nicht: Ich lösche doch die temporäre Liste (TempPageColelction), die hat doch gar nichts mjit der original Liste (PageCollection) zu tun.

Hier noch mal meine Assign- und Clear-Methoden:
Delphi-Quellcode:
procedure TPageCollection.Assign(Source: TPageCollection);
var
  i : Integer;
  j : Integer;
  hobj : Integer;
  hObjSource : Integer;
  Page : TImageEnVect;
begin
  // Klassenattribute kopieren
  PageParent := Source.PageParent;
  ScaleFactor := Source.ScaleFactor;
  for i := 0 to Source.Count - 1 do
  begin
    Page := TImageEnVect.Create(nil);
    // Seiteneigenschaften kopieren
    Page.Name := Source.Items[i].Name;
    Page.Parent := PageParent; //Source.Items[i].Parent;
    Page.Visible := False;
    Page.AllowOutOfBitmapMoving := False;
    Page.BorderStyle := bsNone;
    Page.ScrollBars := ssNone;
    Page.Cursor := crArrow;
    Page.DragMode := dmManual;
    Page.Width := Source.Items[i].Width;
    Page.Height := Source.Items[i].Height;
    Page.OnDragOver := Source.Items[i].OnDragOver;
    Page.OnDragDrop := Source.Items[i].OnDragDrop;
    Page.OnMouseDown := Source.Items[i].OnMouseDown;
    Page.OnObjectDblClick := Source.Items[i].OnObjectDblClick;
    Page.OnLayerNotify := Source.Items[i].OnLayerNotify;
    // Seiten-Layer kopieren. Bitmap nicht mit kopieren.
    for j := 1 to Source.Items[i].LayersCount - 1 do
    begin
      hobj := Page.LayersAdd;
      Page.Layers[hobj].Assign(Source.Items[i].Layers[j]);
    end;
    // Textobjekte
    for j := 0 to Source.Items[i].ObjectsCount - 1 do
    begin
      hobj := Page.AddNewObject;
      hObjSource := Source.Items[i].GetObjFromIndex(j);
      Page.ObjUserData[hObj] := Source.Items[i].ObjUserData[hObjSource];
      Page.ObjKind[hobj] := Source.Items[i].ObjKind[hObjSource];
      Page.ObjLeft[hobj] := Source.Items[i].ObjLeft[hObjSource];
      Page.ObjTop[hobj] := Source.Items[i].ObjTop[hObjSource];
      Page.ObjWidth[hobj] := Source.Items[i].ObjWidth[hObjSource];
      Page.ObjHeight[hobj] := Source.Items[i].ObjHeight[hObjSource];
      Page.ObjTextAlign[hobj] := Source.Items[i].ObjTextAlign[hObjSource];
      Page.ObjFontName[hobj] := Source.Items[i].ObjFontName[hObjSource];
      Page.ObjFontHeight[hobj] := Source.Items[i].ObjFontHeight[hObjSource];
      Page.ObjPenColor[hobj] := Source.Items[i].ObjPenColor[hObjSource];
      Page.ObjFontStyles[hobj] := Source.Items[i].ObjFontStyles[hObjSource];
      Page.ObjText[hobj] := Source.Items[i].ObjText[hObjSource];
      Page.Update;
    end;
    Self.Add(Page);
  end;
end;

procedure TPageCollection.Clear;
var
  i: Integer;
begin
  {mp, 2007-07-03 16:44}
  for i := 0 to Self.FInnerList.Count - 1 do
  begin
    if Assigned(TObject(Self.FInnerList.Items[i])) then
      TObject(Self.FInnerList.Items[i]).Free;
  end;

  Self.FInnerList.Clear;
end;
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat