Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Pointerproblem
Janus - Do 06.03.03 22:09
Titel: Pointerproblem
Hi
Ich bin ein absoluter Neuling, was die Programmierung unter Object-Pascal angeht, doch ich habe fundierte Kenntnisse von C/C++;
Nun, der folgende Code ist aus mir unverständlichen Gründen nicht konpilierbar:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| program research;
{$APPTYPE CONSOLE}
uses SysUtils;
var arr: array[0..9] of Integer; p: ^Integer = nil; pp: ^Integer = nil;
begin arr[0] := 7; arr[5] := 13; p := @arr[5]; pp := p; // bei dieser Zeile erscheint der Fehler "inkompatible Typen" WriteLn(IntToStr(pp^)); ReadLn; end. |
P.S.
Mit ^Variable kann ich ja einen Typisierten Pointer machen, doch wie mache ich einen Pointer auf einen Pointer mit ^^Variable war es nicht möglich ?
Gruss Janus
AndyB - Do 06.03.03 22:35
Pascal ist sehr Typorientiert.
Ein ^Integer ist nicht gleich ein ^Integer.
Jedoch gilt nach
Quelltext
1: 2: 3: 4:
| PInteger = ^Integer; var a: PInteger; b: PInteger; |
dass Typ von a = Typ von b ist.
Kurzum: Du musst einen neuen Typ deklarieren und diesen dann verwenden. Oder du Typecastest auf Teufel komm raus.
Janus - Do 06.03.03 22:39
Hi Andy
Also das verstehe ich nun nicht ganz: ^Integer ist nicht gleich ^Integer ?! :?
Integer ist doch gleich Integer oder etwa nicht, wo ist denn da der Unterschied ??? :shock:
AndyB - Do 06.03.03 22:43
Object Pascal macht daraus 2 Typen. Du musst OP dazu zwingen einen Typen daraus zu machen.
Noch was:
var a, b: ^Integer;Hierbei haben a und b den selben Typ.
Hingegen bei
Quelltext
1: 2: 3:
| var a: ^Integer; b: ^Integer; |
Macht der Compiler 2 nicht kompatible Typen daraus.
Janus - Do 06.03.03 22:50
OK, ich kann mir zwar beim besten Willen nicht vorstellen, wieso der Compiler das macht, aber das muss ich wohl akzepieren...
Mein eigentliches Problem liegt allerdings in folgendem Code, welcher zur Laufzeit eine Speicherschutzverletzung verursacht:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| unit Lib;
interface
uses StdCtrls, Classes, Grids;
function listStrings(ListSelection: TComboBox; TopicList: array of TStringList; DataTable: TStringGrid): Boolean;
implementation function listStrings(ListSelection: TComboBox; TopicList: array of TStringList; DataTable: TStringGrid): Boolean; var i: Integer; sl: ^TStringList;
begin sl := @TopicList[ListSelection.ItemIndex];
if ListSelection.Items.Count = sl^.Count then begin sl^.LoadFromFile(ListSelection.Text+'.txt'); for i:=0 to sl.Count do DataTable.Cells[0,i] := sl^.Strings[i]; Result := true; end else Result:= false; end; end. |
AndyB - Do 06.03.03 22:59
Mit ^TStringList hast du einen Zeiger auf einen Zeiger. Jede class ist automatisch ein Zeiger.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure listStrings(ListSelection: TComboBox; TopicList: array of TStringList; DataTable: TStringGrid); var i: Integer; sl: TStringList;
begin sl := TopicList[ListSelection.ItemIndex]; sl.LoadFromFile(ListSelection.Text+'.txt'); // hier stürzt das Programm ab
for i:=0 to sl.Count do DataTable.Cells[0,i] := sl.Strings[i]; end; |
Hast du mit TStringList.Create auch jedem Element von TopicList[] eine Referenz auf eine Instanz zugewießen.
Janus - Do 06.03.03 23:11
Was meinst du mit Create ? Nein ich habe nirgens ein Create gemacht ! :oops:
Muss ich zuerst jedes Element mit Create erstellen und mit Destroy zerstören, wenn ich es nicht mehr benötige ?
Ach ja, wie gebe ich anschliessen den Speicher wieder frei ??
I habe da x Varianten gesehen:
a := nil;
FreeMem(a);
Dispose(a);
???
Ach ja, gibt es eine Möglichkeit die Grösse eines dynamischen Arrays herauszufinden ? In C/C++ ist das nicht möglich... :(
AndyB - Do 06.03.03 23:54
Length(dynArray)
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var a: array of TStringList; i: Integer; begin SetLength(a, 3); for i := 0 to Length(a) - 1 do a[i] := TStringList.Create; // Instanzen erzeugen
... for i := 0 to Length(a) - 1 do a[i].Free; // Speicher freigeben
SetLength(a, 0); end; |
Ein Dynamisch Array wird von Delphi normalerweise automatisch freigegeben, wenn es den Gültigkeitsraum verlässt. Globale Arrays sollte man dann schon selbst freigeben, wenn man nicht den Speicher bis zum Programmeende belegen will.
Freigeben von dyn. Arrays
Quelltext
1: 2: 3:
| SetLength(a, 0); bzw: a := nil; |
Freigeben von Instanzen (Objekte)
Freigeben von Speicjer, der mit New reserviert wurde
Freigeben von Speicher, der mit GetMem/AllocMem reserviert wurde
Udontknow - Fr 07.03.03 14:31
Hallo!
| Zitat: |
| Was meinst du mit Create ? Nein ich habe nirgens ein Create gemacht ! |
In C++ erstellst du doch Objekte, indem du z.B. schreibst:
Quelltext
1:
| classmyobject myobject=new classmyobject(); |
Aufgebröselt könntest du das auch in zwei Schritten machen:
Variable deklarieren:
Quelltext
1:
| classmyobject myobject; |
Instanz der Klasse erstellen und der Variable zuweisen
Quelltext
1:
| myobject=new classmyobject(); |
Das gleiche musst du für Objekte auch in Delphi machen. Es reicht nicht, eine Variable vom Typ Tstringlist zu deklarieren:
Du musst nun auch eine Instanz von TStringlist erstellen und einen Zeiger auf diese Instanz in dieser Variable ablegen:
Quelltext
1:
| StrL:=TStringlist.Create; |
Delphi verfügt über keine Garbage-Collection, daher musst du sämtliche Objekte auch manuell freigeben (siehe Beitrag über diesem, Stichwort Free).
Cu,
Udontknow
Janus - Fr 07.03.03 21:31
Hei ich danke euch vielmals für die vielen Antworten, ich denke nun habe ich es begriffen !!! :D
Gruss Jnaus
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!