AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TObjectlist.add(record)?

Ein Thema von ozz · begonnen am 6. Mär 2006 · letzter Beitrag vom 7. Mär 2006
Antwort Antwort
Seite 1 von 2  1 2      
ozz

Registriert seit: 26. Jun 2005
131 Beiträge
 
#1

TObjectlist.add(record)?

  Alt 6. Mär 2006, 20:05
Hallo zusammen,
ich möchte zu einer TOjectlist ein Record hinzufügen und bekomme immer einen Typenkonverierungsfehler.
Delphi-Quellcode:
type TCLCategory = record
     id:integer;
     Category:string;
     parent:integer;
end;


type TMyClass = class (TComponent)
private
 FCategory: TObjectList;
 ....
 
procedure TMyClass.irgendetwas;
var current:TCLCategory;
begin
 ....
 FCategory.Add(Current); <-hier
...
end;
Wie kann ich das Problem umgehen?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: TObjectlist.add(record)?

  Alt 6. Mär 2006, 20:13
Hallo.

Um Records zu verwalten solltest du nicht TObjectList nehmen. Nimm TList und beachte, dass du einen Zeiger (@Current) übergeben musst.

Grüße vom marabu
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau
Online

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: TObjectlist.add(record)?

  Alt 6. Mär 2006, 20:49
Gaaaannnz schlimm.


current ist eine lokale Variable! Diese ist nach verlassen der Procedure nicht mehr gültig.

Du kanst nicht mit Records in Listen arbeiten. Da must du schon ein Object draus machen und artig instanzieren. Freigeben nicht vergessen. Aber da kann dir TObjectList mit ownsobjects=true helfen.


Gerd
  Mit Zitat antworten Zitat
ozz

Registriert seit: 26. Jun 2005
131 Beiträge
 
#4

Re: TObjectlist.add(record)?

  Alt 6. Mär 2006, 21:45
Danke Marabu!
Ich habe es mit jetzt TList gemacht.Nur der Vollständigkeit, wie wäre es mit TObjectlist, auch wenn es nicht sauber ist?

Danke!

@bernau
Danke für den Tipp.Hast du dazu ein Code-Snippet? Irgendwie stehe ich auf dem Schlauch.
  Mit Zitat antworten Zitat
Benutzerbild von sniper_w
sniper_w

Registriert seit: 11. Dez 2004
Ort: Wien, Österriech
893 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: TObjectlist.add(record)?

  Alt 6. Mär 2006, 22:44
Mit record kann man sehr wohl arbeiten, genauer gesagt mit den Pointers auf Record.
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    List:TList;
    procedure AddItem( NewItem:pointer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  PmyRec = ^TmyRec;
  TmyRec = record
    item1:Integer;
    item2:Byte;
    item3:string; // vorsicht ;)
  end;

procedure TForm1.AddItem(NewItem: pointer);
begin
  with PmyRec( NewItem )^ do
  begin
    ListBox1.Items.Add( IntToStr( item1 ));
    ListBox1.Items.Add( IntToStr( item2 ));
    ListBox1.Items.Add( item3 );
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  newRec : PmyRec;
  i:Integer;
begin
  Randomize();

  if not Assigned(List) then
  begin
    List := TList.Create;
  end;

  for i:=0 to 10 do
  begin

    New( newRec );

    with newRec^ do
    begin
      item1 := random(100);
      item2 := random(255);
      item3 := 'hallo';
    end;

    List.Add( newRec );
    AddItem( newRec );
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  i:Integer;
  rec:PmyRec;
begin
  for i:= List.Count-1 downto 0 do
  begin
    rec := PmyRec ( List.Items[i] );
    rec^.item3 := '';
    List.Delete(i);
    Dispose(rec);
  end;

  List.Free();
end;
Katura Haris
Es (ein gutes Wort) ist wie ein guter Baum, dessen Wurzel fest ist und dessen Zweige in den Himmel reichen.
  Mit Zitat antworten Zitat
ozz

Registriert seit: 26. Jun 2005
131 Beiträge
 
#6

Re: TObjectlist.add(record)?

  Alt 7. Mär 2006, 05:46
Guten Morgen sniper_w!
Danke für dein sehr ausfühliches Beispiel. Ich habe es etwas anders gemacht, aber ich lerne immer gern dazu.
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau
Online

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: TObjectlist.add(record)?

  Alt 7. Mär 2006, 08:09
Zitat von sniper_w:
Mit record kann man sehr wohl arbeiten, genauer gesagt mit den Pointers auf Record.
ACK. So gehts natürlich, da du mit "New" bzw "Dispose" den Speicher reservierst und auch wieder freigibst.

Marabu hat sich in seinem Beispiel aber auf die Variable "current" bezogen. Dies ist eine lokale Variable in der Procedure, die nach Beendigung der Procedure schlicht nicht mehr vorhanden ist und somit der Zeiger ins Nirvana zeigt. Dumm ist, daß die Belegung des Speichers (da wo der Pointer hinzeigt) tatsächlich noch eine Zeit lang so ist wie Sie sein sollte. Aber irgendwann wird dieser Speicherbereich von anderen Daten überschrieben. Darauf wollte ich nur aufmerksam machen, bevor stundenlang nach Fehlern gesucht wird.

Übrigens finde ich es eleganter mit Objekten zu arbeiten statt mit Pointern auf Records. Aber das ist reine Geschmackssache.

Gerd
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau
Online

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: TObjectlist.add(record)?

  Alt 7. Mär 2006, 08:19
Zitat von ozz:
Ich habe es mit jetzt TList gemacht.Nur der Vollständigkeit, wie wäre es mit TObjectlist, auch wenn es nicht sauber ist?
TList und TObjectlist unterscheiden sich nicht besonders. Im Gegensatz zu TList kannst du aber bei TObjectlist mit dem Property ownsobjects angeben, daß TObjectlist die zugefügten Objekte wieder freigibt, wenn die einzelnen Elemente entfernt werden bzw. die glanze Liste freigegeben wird.


Zitat von ozz:
Danke für den Tipp.Hast du dazu ein Code-Snippet? Irgendwie stehe ich auf dem Schlauch.

Hier mal eben schnell zusamengeschrieben:


Delphi-Quellcode:
type TCLCategory = class (TObject) // <- kein record sondern ein Object
     id:integer;
     Category:string;
     parent:integer;
end;


type TMyClass = class (TComponent)
private
FCategory: TObjectList;
....


procedure TMyClass.create;
begin
FCategory:=TObjectList.create;
FCategory.ownsobjects:=true;
end;

....

procedure TMyClass.irgendetwas;
var
  current:TCLCategory;
begin
....
current:=TCLCategory.create;

// Hier die Were zuweisen
current.Category:='Irgendein String';


FCategory.Add(Current);
...
end;
  Mit Zitat antworten Zitat
Benutzerbild von sniper_w
sniper_w

Registriert seit: 11. Dez 2004
Ort: Wien, Österriech
893 Beiträge
 
Delphi 6 Enterprise
 
#9

Re: TObjectlist.add(record)?

  Alt 7. Mär 2006, 14:31
Zitat von bernau:
Aber irgendwann wird dieser Speicherbereich von anderen Daten überschrieben. Darauf wollte ich nur aufmerksam machen, bevor stundenlang nach Fehlern gesucht wird.
Kannst du das bitte mehr dazu sagen.
Katura Haris
Es (ein gutes Wort) ist wie ein guter Baum, dessen Wurzel fest ist und dessen Zweige in den Himmel reichen.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#10

Re: TObjectlist.add(record)?

  Alt 7. Mär 2006, 16:00
Hallo Leute,

mein Beitrag #2 war wohl Auslöser für eine heiße Diskussion ganz nach dem Vorbild Shakespeare's Much Ado about Nothing: Der Klammerzusatz (@Current) war nur ein missglückter Versuch meinen allgemein gehaltenen Beitrag doch noch etwas in Bezug zum Code von ozz zu setzen. Wer mir zutraut, ich würde die Adresse einer Variablen auf dem Stack mit der Adresse einer Variablen auf dem Heap verwechseln, der kränkt mich. Aber Gerd hat sicherlich recht mit seinem Hinweis - wer weiß wen ich sonst noch alles ungewollt aufs Glatteis schicke.

Der Speicher für lokale Variablen einer Funktion oder Prozedur wird vor dem Aufruf des Codes durch Verschieben des stack pointers bereit gestellt. Nach der Rückkehr aus der Funktion wird dieser Speicher wieder zur Verfügung gestellt. Bei erneutem Aufruf der Funktion kurz danach kann es passieren, dass man auf die alten Inhalte zugreifen kann. Generell wird dieser Speicherbereich aber bei Bedarf wieder von anderen Routinen verwendet. Will ich selbst die Lebensdauer des Speichers bestimmen, dann muss ich den Speicher entweder über globale Variablen bereit stellen oder ich verwalte den Speicher über die entsprechenden Funktionen auf dem Heap.

@sniper_w: eigentlich war ich davon überzeugt, dass dein Code-Beispiel die Dinge bereits ausreichend beleuchtet hatte, aber dein letzter Beitrag hat mich dann doch noch zu einem beherzten Griff in die Tasten bewogen.

Freundliche Grüße vom marabu
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:54 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