Underlig fejl med dynamiske arrays i delphi
Jeg får fejlen "Invalid Pointer operation" nå jeg køre min kode. Programmer analysere en string og kan finde ud af udtryk så som 3+4+8*6, men den kan dog endnu ikke finde ud af /.Nå jeg køre koden med 3+5 kan den godt finde ud af det. Hvis jeg skriver 3+5+8 kan den ikke, anden gang den køre koden kommer den med fejlen.
Hvad kan der være galt? Det er jo den samme kode programmet køre.
---------- Kode --------------
program Project3;
{$APPTYPE CONSOLE}
uses
Stack, SysUtils;
var
sExpression: String;
iNumberOfNumbers, iRunTimes: Integer;
NumberStack: TNumStack;
OpStack: TOpStack;
const
Operatorer= ['*', '/', '+', '-'];
Tal=['0','1','2','3','4','5','6','7','8','9'];
{----------------------------------------
Begyndelsen på CheckPriority Funktionen
Funktion:
Denne funktion modtager to char's, derefter
undersøger den hvad for et af de to der har
højest prioritet (* før +).
Hvis den første operator er højest retunere
funktionen true. Hvis den anden operator er højest
eller hvis begge operatore har lige stor prioritet
returner den false.
Kaldes fra:
OpHandle Funktionen
---------------------------------------}
function CheckPriority(var cPriorityCheck1, cPriorityCheck2: Char): boolean;
var
iPriority1, iPriority2: Integer;
bCheckPriority: boolean;
begin
bCheckPriority:=false;
// IF * OR / = 2 ELSE 1
if (cPriorityCheck1='*') OR (cPriorityCheck1='/') then iPriority1:=2 else iPriority1:=1;
if (cPriorityCheck2='*') OR (cPriorityCheck2='/') then iPriority2:=2 else iPriority2:=1;
// If c>d return true
if (iPriority1>iPriority2) then bCheckPriority:=true;
// If c<=d return false
if (iPriority2>=iPriority1) then bCheckPriority:=false;
Result:=bCheckPriority;
end;
{----------------------------------------
Begyndelsen på OpHandle Funktionen
Funktion:
OpHandel funktionen kaldes fra main og fortæller
case udtrykket om den skal udregne nu eller vente.
Funktionen styre også operator stacken, ved at Pop'e
op Push'e operatore ind i den.
Kaldes fra:
Main
---------------------------------------}
function OpHandle(sOpHandel: string): boolean;
var
cTempPeekValue : Char;
begin
if (OpStack.Empty) then
begin
OpStack.Push(sExpression[iRunTimes]);
Result:=False;
end
else
begin
cTempPeekValue:=OpStack.Peek;
if CheckPriority(sExpression[iRunTimes], cTempPeekValue) then // Hvis sExpression[iRunTimes] har højere prioritet end cTempPeekValue.
begin
opstack.Push(sExpression[iRunTimes]); // Gem Operatoren væk på OpStacken til en anden gang.
result:=False;
end
else
begin // Lavere prioritet, udregn nu
Result:=True;
end;
end;
end;
{----------------------------------------
Begyndelsen på LargeNumbers Procedure
Funktion:
Hvis programmet møder tal med flere cifre
gemmer den dem i første omgang bare som enkelte
tal i NumberStacken.
Funktionen kaldes når programmet møder en operator
i strengen og hvis iNumberOfNumbers er større end 1.
(Hvis iNumberOfNumbers er større end 1 har programmet
mødt mere end et cifre siden sidste operator)
Kaldes fra:
Main (Case Strukturen)
---------------------------------------}
Procedure LargeNumbers;
var
a, b, c : String;
i : integer;
begin
i:=0;
while i<=(iNumberOfNumbers-2) do
begin
a:=IntToStr(NumberStack.Pop);
b:=IntToStr(NumberStack.Pop);
c:=a+b;
NumberStack.Push(StrToInt(c));
i:=i+1;
end;
end;
{----------------------------------------
Begyndelsen på Calculate Procedure
Funktion:
Kaldes fra:
Main (While-loop) og Slutning
---------------------------------------}
procedure Calculate;
begin
Write('1. Length of Number array: ');
WriteLn(NumberStack.MyLength);
Write('1. Length of Op array: ');
WriteLn(OpStack.MyLength);
case OpStack.Pop of
'*': begin
NumberStack.push(NumberStack.Pop * NumberStack.Pop);
end;
'/': begin
NumberStack.push(NumberStack.Pop div NumberStack.Pop);
end;
'-': begin
NumberStack.push(NumberStack.Pop - NumberStack.Pop);
end;
'+': begin
NumberStack.push(NumberStack.Pop + NumberStack.Pop);
end;
end;
WriteLn(NumberStack.Peek);
if (iRunTimes>0) then
begin
OpStack.Push(sExpression[iRunTimes]);
end;
end;
{----------------------------------------
Begyndelse på Main
Funktion:
Modtager udtrykket.
Analysere det.
Deler det op i operatore og tal.
Foretager også nogle udregninger.
---------------------------------------}
begin
// Initialisere de to stakke
NumberStack:=TNumStack.Create;
OpStack:=TOpStack.Create;
// Modtager Udtrykker
Write('Expression:');
ReadLn(sExpression);
iRunTimes:=length(sExpression);
while iRunTimes>=1 do // Starter bagfra i ligningen og køre fremad.
begin
if sExpression[iRunTimes] in Operatorer then
begin
if (iNumberOfNumbers>1) then // Hvis der har været flere cifret tal, så læg det tal sammen.
begin
LargeNumbers;
end;
iNumberOfNumbers:=0; // Koden har nu mødt en operator, derfor nul stilles iNumberOfNumbers.
if (OpHandle(sExpression[iRunTimes]) = false) then // Hvis den værdi programmet møder i sExpression[iRunTimes] er af højere prioritet end den operator der ligger øverst på OpStacken så returner OpHandel false, og værdien bliver smidt ind i toppen af OpStacken.
begin
// Operatoren bliver lagt ind i OpStacken i OpHandel funktionen.
end
else // Hvis programmet møder en operator der har lavere eller samme prioritet end den operator der ligger på OpStacken, så henter den de to øverste tal fra NumberStacken og bruger operatoren op dem.
begin
Calculate;
end;
iRunTimes:=iRunTimes-1; //Programmet er nået en længere ind i udtrykket
end // Slut på if-sætning
else begin
if sExpression[iRunTimes] in Tal then
begin
NumberStack.Push(StrToInt(sExpression[iRunTimes]));
iNumberOfNumbers:=iNumberOfNumbers+1;
iRunTimes:=iRunTimes-1;
end;
end; // Slut på Else
end; // Slut på While-Loop
WriteLn(NumberStack.Peek);
WriteLn(OpStack.Peek);
Calculate;
WriteLn(NumberStack.Pop);
readLn;
End.
---------- Stack Class ---------
unit Stack;
interface
// NumberStack
type
TNumStack = class
NumStackArray : Array of integer;
procedure Push(iPushvalue : Integer); // Bruges til at pushe en værdi ind i stacken
Function Pop: Integer; // Henter den øverste værdi ud af stacken
Function Peek: Integer; // Opgiver den øverste værdi i stacken
procedure ClearStack; // Ryder hele stacken
function Empty : boolean; // Ser om stacken er tom
Constructor Create;
function MyLength:Integer;
private
{ Private declarations }
public
{ Public declarations }
end;
// Operator Stack
type
TOpStack = class
OpStackArray : Array of char;
procedure Push(cPushvalue : char); // Bruges til at pushe en værdi ind i stacken
Function Pop : Char; // Henter den øverste værdi ud af stacken
Function Peek : Char; // Opgiver den øverste værdi i stacken
procedure ClearStack; // Ryder hele stacken
function Empty : boolean; // Ser om stacken er tom
Constructor Create;
function MyLength:Integer;
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
uses
SysUtils, StrUtils;
{------------------------------------------
Begyndelse af Number Stackens funktioner
------------------------------------------}
Constructor TNumStack.Create;
var t : integer;
begin
SetLength(NumStackArray, 1);
for t:=0 to Length(NumStackArray) do
begin
NumStackArray[t]:=0;
end;
end;
// Sæt alle værdier i stacken til 0
procedure TNumStack.ClearStack;
var t : integer;
begin
for t:=0 to Length(NumStackArray) do
begin
NumStackArray[t]:=0;
end;
end;
function TNumStack.MyLength:Integer;
begin
Result:=Length(NumStackArray);
end;
// Ser om stacken er tom
function TNumStack.Empty : boolean;
var
i : integer;
Empty: Boolean;
begin
Empty:=True;
for i:=0 to Length(NumStackArray) do
begin
if (Length(NumStackArray) > 1) then
begin
Empty:=False;
break;
end;
end;
Result:=Empty;
end;
Function TNumStack.Pop: Integer;
var
i : integer;
begin
Result:=NumStackArray[0];
if (Length(NumStackArray) > 2) then
begin
for i:=0 to (Length(NumStackArray)-2) do
begin
NumStackArray[i]:=NumStackArray[i+1];
NumStackArray[i+1]:=0;
end;
end
else
begin
NumStackArray[0]:=0;
NumStackArray[1]:=0;
end;
SetLength(NumStackArray, (Length(NumStackArray)-1));
end;
// Push værdier til toppen af stacken
procedure TNumStack.Push(iPushValue : Integer);
var
i : integer;
Begin
SetLength(NumStackArray, (Length(NumStackArray)+1));
i:=Length(NumStackArray);
while i>=1 do
begin
NumStackArray[i]:=NumStackArray[i-1];
NumStackArray[i-1]:=0;
i:=i-1;
end;
NumStackArray[0]:=iPushValue;
end;
// Læser den øverste værdi fra stacken uden at slette den.
Function TNumStack.Peek: Integer;
begin
Result:=NumStackArray[0];
end;
{------------------------------------------
Slutning på Number Stack funktioner
------------------------------------------}
{------------------------------------------
Begyndelse af Operator Stackens funktioner
------------------------------------------}
Constructor TOpStack.Create;
var t : integer;
begin
SetLength(OpStackArray, 1);
for t:=0 to Length(OpStackArray) do
begin
OpStackArray[t]:='A';
end;
end;
// Sæt alle værdier i stacken til 0
procedure TOpStack.ClearStack;
var t : integer;
begin
for t:=0 to Length(OpStackArray) do
begin
OpStackArray[t]:='A';
end;
end;
// Ser om stacken er tom, Result er false hvis den ikke er tom.
function TOpStack.Empty : boolean;
var
i : integer;
Empty: Boolean;
begin
Empty:=True;
for i:=0 to Length(OpStackArray) do
begin
if (Length(OpStackArray) > 1) then
begin
Empty:=False;
break;
end;
end;
Result:=Empty;
end;
Function TOpStack.Pop : Char;
var
i : integer;
begin
Result:=OpStackArray[0];
if (Length(OpStackArray) > 2) then
begin
i:=0;
while i<=(Length(OpStackArray)-2) do
begin
OpStackArray[i]:=OpStackArray[i+1];
OpStackArray[i+1]:='A';
i:=i+1;
end;
end
else
begin
OpStackArray[0]:='A';
OpStackArray[1]:='A';
end;
SetLength(OpStackArray, ((Length(OpStackArray))-1));
end;
// Push værdier til toppen af stacken
procedure TOpStack.Push(cPushValue : Char);
var
i : integer;
Begin
SetLength(OpStackArray, ((Length(OpStackArray)+1)));
i:=Length(OpStackArray);
while i>=1 do
begin
OpStackArray[i]:=OpStackArray[i-1];
OpStackArray[i-1]:='A';
i:=i-1;
end;
OpStackArray[0]:=cPushValue;
end;
// Læser den øverste værdi fra stacken uden at slette den.
Function TOpStack.Peek : Char;
begin
Result:=OpStackArray[0];
end;
function TOpStack.MyLength:Integer;
begin
Result:=Length(OpStackArray);
end;
{------------------------------------------
Slut på Operator Stack funktioner
------------------------------------------}
End.