Autor Beitrag
Magic J
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66

WinXP Prof., Vista
Delphi6, Delphi 2009, Java(Eclipse), C++, Basic
BeitragVerfasst: Mi 20.08.08 23:45 
Hallo,

ich bin gerade dabei einen kleinen Formel-Parser zu programmiern, allerdings nur zu grafischen Darstellung der Formeln.
Doch darum geht es bei meinem Problem nicht direkt:

Ich habe zum Speichern der Zahlen und Operanten eine eigene Liste definiert, die ich mir von "TList" abgeschaut habe.
Deren Einträge soll allerdings eben nicht vom Typ "Pointer" sein, sondern hiervon:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type
  TFormelTeil= packed record
    Str:String;
    Art:Byte;
  End;


Die folgende Unit beinhaltet mein Resultat:
ausblenden volle Höhe Delphi-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:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
unit FormelListUnit;

interface

uses
  Windows, Messages, Classes ,Dialogs;

type
  TFormelTeil= packed record
    Str:String;
    Art:Byte;
  End;

  PFTeile = ^TFTeile;
  TFTeile = array[0..MaxListSize - 1of TFormelTeil;

  TFTList = class(TObject)
  private
    FFTList: PFTeile;
    FCount: Integer;
    FCapacity: Integer;
  protected
    function Get(Index: Integer): TFormelTeil;
    procedure Grow; virtual;
    procedure SetCapacity(NewCapacity: Integer);
    procedure SetCount(NewCount: Integer);
    procedure Put(Index: Integer; Item: TFormelTeil);
  public
    procedure PutInLast(Item: TFormelTeil);
    destructor Destroy; override;
    function Add(Item: TFormelTeil): Integer;
    procedure Clear; virtual;
    procedure Delete(Index: Integer);
    procedure Exchange(Index1, Index2: Integer);
    function Expand: TFTList;
    function First: TFormelTeil;
    procedure Insert(Index: Integer; Item: TFormelTeil);
    function Last: TFormelTeil;
    procedure Move(CurIndex, NewIndex: Integer);
    property Capacity: Integer read FCapacity write SetCapacity;
    property Count: Integer read FCount write SetCount;
    property Items[Index: Integer]: TFormelTeil read Get write Put; default;
    property List: PFTeile read FFTList;

    function Str(Index: Integer): String;
    function Art(Index: Integer): Byte;
  end;

implementation

{ TFTList }

function TFTList.Art(Index: Integer): Byte;
begin
  Result:=0;
  if (Index < 0or (Index >= FCount) then exit;
  Result := Get(Index).Art;
end;

function TFTList.Str(Index: Integer): String;
begin
  Result:='';
  if (Index < 0or (Index >= FCount) then exit;
  Result := Get(Index).Str;
end;

destructor TFTList.Destroy;
begin
  Clear;
end;

function TFTList.Add(Item: TFormelTeil): Integer;
begin
  Result := FCount;
  if Result = FCapacity then
    Grow;
  Items[Result]:= Item;
  Inc(FCount);
end;

procedure TFTList.Clear;
begin
  SetCount(0);
  SetCapacity(0);
end;

procedure TFTList.Delete(Index: Integer);
var
  Temp: TFormelTeil;
begin
  if (Index < 0or (Index >= FCount) then exit;

  Temp := Items[Index];
  Dec(FCount);
  if Index < FCount then
    System.Move(FFTList^[Index + 1], FFTList^[Index],(FCount - Index) * SizeOf(TFormelTeil));
end;

procedure TFTList.Exchange(Index1, Index2: Integer);
var
  Item: TFormelTeil;
begin
  if (Index1 < 0or (Index1 >= FCount) then  exit;
  if (Index2 < 0or (Index2 >= FCount) then  exit;
  Item := FFTList^[Index1];
  FFTList^[Index1] := FFTList^[Index2];
  FFTList^[Index2] := Item;
end;

function TFTList.Expand: TFTList;
begin
  if FCount = FCapacity then
    Grow;
  Result := Self;
end;

function TFTList.First: TFormelTeil;
begin
  Result := Get(0);
end;

function TFTList.Get(Index: Integer): TFormelTeil;
begin
  if (Index < 0or (Index >= FCount) then exit;
  Result := FFTList^[Index];
end;

procedure TFTList.Grow;
var
  Delta: Integer;
begin
  if FCapacity > 64 then
    Delta := FCapacity div 4
  else
    if FCapacity > 8 then
      Delta := 16
    else
      Delta := 4;
  SetCapacity(FCapacity + Delta);
end;

procedure TFTList.Insert(Index: Integer; Item: TFormelTeil);
begin
  if (Index < 0or (Index > FCount) then exit;
  if FCount = FCapacity then
    Grow;
  if Index < FCount then
    System.Move(FFTList^[Index], FFTList^[Index + 1],
      (FCount - Index) * SizeOf(TFormelTeil));
  FFTList^[Index] := Item;
  Inc(FCount);
end;

function TFTList.Last: TFormelTeil;
begin
  Result := Get(FCount - 1);
end;

procedure TFTList.Move(CurIndex, NewIndex: Integer);
var
  Item: TFormelTeil;
begin
  if CurIndex <> NewIndex then
  begin
    if (NewIndex < 0or (NewIndex >= FCount) then exit;
    Item := Get(CurIndex);
    Delete(CurIndex);
    Insert(NewIndex, Item);
    FFTList^[NewIndex] := Item;
  end;
end;

procedure TFTList.Put(Index: Integer; Item: TFormelTeil);
var
  Temp: TFormelTeil;
begin
  if (Index < 0or (Index >= FCount) then exit;
  if (Item.Str <> FFTList^[Index].Str)and
     (Item.Art <> FFTList^[Index].Art)then
  begin
    Temp := FFTList^[Index];
    FFTList^[Index] := Item;
  end;
end;

procedure TFTList.SetCapacity(NewCapacity: Integer);
begin
  if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then exit;
  if NewCapacity <> FCapacity then
  begin
    ReallocMem(FFTList, NewCapacity * SizeOf(TFormelTeil));
    FCapacity := NewCapacity;
  end;
end;

procedure TFTList.SetCount(NewCount: Integer);
var
  I: Integer;
begin
  if (NewCount < 0or (NewCount > MaxListSize) then  exit;
  if NewCount > FCapacity then
    SetCapacity(NewCount);
  if NewCount > FCount then
    FillChar(FFTList^[FCount], (NewCount - FCount) * SizeOf(TFormelTeil), 0)
  else
    for I := FCount - 1 downto NewCount do
      Delete(I);
  FCount := NewCount;
end;

procedure TFTList.PutInLast(Item: TFormelTeil);
begin
  Put(Count-1,Item);
end;

end.


Die im Quellcode makierten Zeilen führen allerdings leider bei der Verwendung wie hier(drunter) zu Fehlern:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
uses FormelListUnit;

procedure TForm1.Button1Click(Sender: TObject);
Var F:TFTList;
    FT:TFormelTeil;
begin

  F:=TFTList.Create;
  FT.Str:='123';
  FT.art:=1;

  F.Add(FT);

  Label1.Caption:=IntToStr(F.Art(0));

end;


Fehlermeldung: "Invalid pointer operation"

Ich habe leider keine Ahnung von Pointern und deren Verwendung.
Soweit ich das richtig erkannt habe, muss der Fehler wohl schon beim "Schreiben" zustande kommen...


Hoffe, dass ihr mir beim Lösen des Problems weiterhelfen könnt!

Danke im Voraus für Antworten!


Gruß, Jonas
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 26.08.08 11:43 
ich habe noch nie ein packed record verwenden (muss mich gleich mal informieren, was das eig. ausmacht), aber:

user profile iconMagic J hat folgendes geschrieben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function TFTList.Add(Item: TFormelTeil): Integer;
begin
  Result := FCount;
  if Result = FCapacity then
    Grow;
  Items[Result]:= Item;
  Inc(FCount);
end;




probiers mal so
ausblenden Delphi-Quelltext
1:
2:
Items[Result].Art:= Item.Art;
Items[Result].Strs:= Item.Strs;

und guck dir mal das Result an, dass ist irgendwie komisch *nachdenk*
weil einerseits Result=FCount, andererseits aber im array Items[Result]. (Im array ist das letzte element count-1)

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)