Autor Beitrag
Hirschi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP, Vista, 7
Delphi 2009 Ent., C# (VS 2010 Ent.), C++ (VS 2010 Ent.), Java (Eclipse)
BeitragVerfasst: Fr 03.12.10 18:54 
Hallo Leute,
seit ein paar Stunden hänge ich an folgendem Problem:

Ich brauche einen eigenen Datentyp. Dafür wollte ich einen Record nehmen. Ungefähr so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
type  TStep = record
     fromPos  : Integer;
     toPos    : Integer;
end;

Davon will ich beliebig viele in einer Liste verwalten. Dazu verwende ich eine Liste:
ausblenden Delphi-Quelltext
1:
Steps : TList<TStep>;					


Die wird nun erstellt und ein paar Elemente hinzugefügt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Steps := TList<TStep>.Create();
...
st.fromPos := Random(100);
st.toPos   := Random(100);
Steps.Add(st);
st.fromPos := Random(100);
st.toPos   := Random(100);
Steps.Add(st);


Das klappt auch alles ohne Fehler. Will ich aber nun ein beliebiges Element löschen, bekomme ich eine Zugriffsverletzung:
ausblenden Delphi-Quelltext
1:
Steps.Delete(Steps.Count-1);					

Wenn ich statt meinem Record einen primitven Datentyp (z.B. Integer) nehme, dann funktionierts es. Ich muss also irgendwas mit dem Record nicht verstanden haben. Hoffe, ihr habt einen Tipp.

MfG
Hirschi
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 03.12.10 19:04 
Moin und :welcome: im Forum!

Du hast leider einen wichtigen Teil in deinem Code nicht gezeigt: die Speicherverwaltung. ;) Weiterhin wäre es auch nicht ganz unwichtig, wie die Fehlermeldung genau aussieht.

btw: Nimm lieber ein Objekt und die TObjectList, das ist besser als das Pointergehampel mit der TList... :? :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Fr 03.12.10 21:00 
@Narses

ich vermute alle Pointer zeigen auf die gleiche Variable
ausblenden Delphi-Quelltext
1:
 st:TStep					

möglicherweise, sogar auf dem Stack...

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Hirschi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP, Vista, 7
Delphi 2009 Ent., C# (VS 2010 Ent.), C++ (VS 2010 Ent.), Java (Eclipse)
BeitragVerfasst: Fr 03.12.10 21:02 
Danke für die schnelle Antwort, Narses! :)
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Du hast leider einen wichtigen Teil in deinem Code nicht gezeigt: die Speicherverwaltung. ;)
Na, da gibt es keine besondere. Deshalb nehm ich doch TList aus der Uni Generics.Collection und nicht eine normale TList.
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

Weiterhin wäre es auch nicht ganz unwichtig, wie die Fehlermeldung genau aussieht.
Es ist schlicht eine Zugriffsverletzung auf eine Adresse im Speicher. Sie wird geworfen, wenn ich das Element löschen will. Insofern kann ich das nicht genauer schreiben, denn die Adresse ist ja jedesmal anders.
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
btw: Nimm lieber ein Objekt und die TObjectList, das ist besser als das Pointergehampel mit der TList... :? :nixweiss:
Richtig, das "Pointergehampel" wollte ich umgehen. ;)

MfG
Hirschi
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 03.12.10 21:15 
user profile iconHirschi hat folgendes geschrieben Zum zitierten Posting springen:
Deshalb nehm ich doch TList aus der Uni Generics.Collection und nicht eine normale TList.
Das hat aber nichts damit zu tun, dass du auch neuen Speicher für jeden Record allozieren und evtl. am Ende wieder freigeben musst (ob die Freigabe bei der Collection automatisch passieren kann, weiß ich nicht). :nixweiss:

user profile iconHirschi hat folgendes geschrieben Zum zitierten Posting springen:
Richtig, das "Pointergehampel" wollte ich umgehen. ;)
Und warum machst du es dir dann unnötig schwer? Genau dafür gibt es wie schon geschrieben wurde Klassen und Objekte.
Hirschi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP, Vista, 7
Delphi 2009 Ent., C# (VS 2010 Ent.), C++ (VS 2010 Ent.), Java (Eclipse)
BeitragVerfasst: Mo 06.12.10 16:48 
So wie ich es im Eingangsbeitrag beschrieben habe, funktioniert es auch bei einem Kollegen auf dem Rechner. Er verwendet allerdings Delphi 2010. Heißt, es muss wohl an meiner D2009-Installation liegen...sehr ärgerlich. Ich habe das nun mit Debug-DCUs durchlaufen und das Programm stützt in der DoDelete-Prozedur der Generics.Collection.pas bei der Zeile
FItems[Index] := Default(T);
ab. An der Prozedur ist von D2009 auf D2010 nichts passiert...tja, dann werd ich wohl was anderes (TObjectList) nehmen... Aber, theoretisch ginge mein Weg auch ;)

MfG
Hirschi
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 06.12.10 17:07 
Moin!

user profile iconHirschi hat folgendes geschrieben Zum zitierten Posting springen:
So wie ich es im Eingangsbeitrag beschrieben habe, funktioniert es auch bei einem Kollegen auf dem Rechner.
[...]
Aber, theoretisch ginge mein Weg auch
Wenn du mit records arbeitest, dann wird das ganz sicher nicht korrekt funktionieren, denn für die Speicherverwaltung bei records ist immer zusätzlicher Code nötig, das hat Delphi (und auch TP) noch nie selbst gemacht. :mahn: Insofern wundert mich, dass es irgendwo "laufen soll" (was man dann noch mal näher untersuchen sollte, heißt ja vielleicht auch nur: "stürzt nicht sofort ab" :mrgreen:)... :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Hirschi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP, Vista, 7
Delphi 2009 Ent., C# (VS 2010 Ent.), C++ (VS 2010 Ent.), Java (Eclipse)
BeitragVerfasst: Mo 06.12.10 18:06 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Moin!

Wenn du mit records arbeitest, dann wird das ganz sicher nicht korrekt funktionieren, denn für die Speicherverwaltung bei records ist immer zusätzlicher Code nötig, das hat Delphi (und auch TP) noch nie selbst gemacht. :mahn: Insofern wundert mich, dass es irgendwo "laufen soll" (was man dann noch mal näher untersuchen sollte, heißt ja vielleicht auch nur: "stürzt nicht sofort ab" :mrgreen:)... :nixweiss:

Speicher beziehen und freigeben macht die TList<T> für dich, denn die Generics-Sachen haben eine eigene Speicherverwaltung.

Übrigens läuft es jetzt auch bei mir (endlich!), da ich eine Update der IDE gemacht habe. Auch bei einem anderen Kollgen mit D2009 läuft es genau wie beschrieben.

MfG
Hirschi
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 06.12.10 18:39 
Moin!

user profile iconHirschi hat folgendes geschrieben Zum zitierten Posting springen:
Speicher beziehen und freigeben macht die TList<T> für dich, denn die Generics-Sachen haben eine eigene Speicherverwaltung.
Das glaube ich gerne, wenn es um Objekte geht. ;) Aber bei records nicht. :idea: Ab D2k9 war doch FastMM mit dabei, da kann man doch eine Memory-Leak-Prüfung einschalten, das würde ich an deiner Stelle mal tun und sehen, ob da wirklich das passiert, was du erwartest... :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 06.12.10 20:19 
Ich kann zwar nicht selbst nachschauen, aber ich fürchte, ihr seht gerade Zeiger, wo keine sind ;) . Nach der Instanzierung der Generics dürfte ja ganz grob das (zumindest innerhalb des Compilers) dranstehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type TList<TStep> = class
  ...
  var FItems : array of TStep;
  ...
  public procedure Add(aObj: TStep);

Man kann natürlich auch eine TList<TStep^> instanzieren (geh ich einfach mal von aus :) ), aber im obigen Fall sollten keine Zeiger beteiligt sein.

_________________
>λ=
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mo 06.12.10 20:49 
Ich habe es nachdem ich es auch nicht glauben wollte bei folgendem Thread

www.delphipraxis.net...record-new-post.html

einmal komplett durchgespielt, geht tatsächlich problemlos und sauber, zumindest unter XE.

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 06.12.10 23:26 
Moin!

OK, überzeugt. ;) (das mit dem internen dynamischen Array ist natürlich die Erklärung! :think:)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Hirschi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP, Vista, 7
Delphi 2009 Ent., C# (VS 2010 Ent.), C++ (VS 2010 Ent.), Java (Eclipse)
BeitragVerfasst: Do 09.12.10 11:16 
Danke für das arbeitsreiche Schlusswort, bummi ;) Und danke an alle Mitdiskutanten!

MfG
Hirschi