Solved

Save dfifferent variable-types on stack?

Posted on 2002-05-03
17
207 Views
Last Modified: 2010-04-04
Is there any way to save different types
of variables (objects of various size, integer, doubles,
strings)
on a stack, like this:

var stack : array[..MAXSTACKSIZE] of pointer;

procedure push(obj:pointer)
var newstackcontent:pointer;
begin  
  newstackcontent:=somekindeof_allocatemem(obj,getsizeof(obj));
  somekindeof_copy(obj,newstackcontent);
  stack[stackptr]:=newstackcontent;
  inc(stackptr);
end;

and restore them:

procedure pop(var obj:pointer);
var stackcontent:pointer;
begin  
  stackcontent:=stack[stackptr];
  somekindeof_copy(stackcontent,obj);
  dec(stackptr);
  somekindeof_freemem(stackcontent);
end;

More specific:

Is there a general working way to implement
somekindeof_copy, somekindof_allocatemem and
somekindof_freemem without doing the
type conversions??

Thanks for help (implementations??),

Gamba




0
Comment
Question by:Gamba
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
17 Comments
 
LVL 2

Expert Comment

by:dMa
ID: 6988787
like this :

type
 TMatrix = RMatrix ;

 Rmatrix = Record
    FPointer    : Pointer ;
    FInteger    : Integer ;
    FString     : Pointer ;
    FStringList : TStringList ;
 end;

var
 MatrixStack = array [0..TMSLeanght]of TMatrix ;
 

1. you have to allocate memory of some TMatrixStack you will use like
  new( matrixstack[0] );
  new( matrixstack[1] );

 
 
0
 

Author Comment

by:Gamba
ID: 6988868
This means, I would still have to know,
which element of the record I would have to allocate
(matrixstack[0] or matrixstack[1]).

So, I don't really need the matrix, I could also
use this:

case (obtype) of
  0: new(FPointer);
  1 :new(FInteger);
end;

My problem is, that I don't know objtype.
0
 
LVL 1

Expert Comment

by:Alone
ID: 6988961
See contnrs.pas - standard Delphi containers
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:Gamba
ID: 6989210
Sorry, this file is not present in Delphi Standard...
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 6989656
try something like this (not tested):


type
  PMyData = ^TMyData;
  TMyData = record
    case Kind: Byte of
      0: (AsInteger: Integer);
      1: (AsDouble: Double);
      2: (AsString: ShortString);
  end;

  TMyDataStack = class
  private
    FList: TList;
  public
    constructor Create;
    destructor Destroy; override;

    function Count: Integer;
    function Peek: TMyData;
    function Pop: TMyData;
    procedure Push(Value: Integer); overload;
    procedure Push(Value: Double); overload;
    procedure Push(Value: ShortString); overload;
  end;

implementation

{ TMyDataStack }

constructor TMyDataStack.Create;
begin
  inherited Create;
  FList := TList.Create;
end;

destructor TMyDataStack.Destroy;
begin
  FList.Free;
  inherited Destroy;
end;

function TMyDataStack.Count: Integer;
begin
  Result := FList.Count;
end;

function TMyDataStack.Peek: TMyData;
begin
  Result := PMyData(FList[FList.Count - 1])^;
end;

function TMyDataStack.Pop: TMyData;
var
  P: PMyData;
begin
  P := FList[FList.Count - 1];
  Result := P^;
  FreeMem(P);
  FList.Delete(FList.Count - 1);
end;

procedure TMyDataStack.Push(Value: Integer);
var
  P: PMyData;
begin
  P := AllocMem(SizeOf(TMyData));
  try
    P^.Kind := 0;
    P^.AsInteger := Value;
    FList.Add(P);
  except
    FreeMem(P);
    raise;
  end;
end;

procedure TMyDataStack.Push(Value: Double);
var
  P: PMyData;
begin
  P := AllocMem(SizeOf(TMyData));
  try
    P^.Kind := 1;
    P^.AsDouble := Value;
    FList.Add(P);
  except
    FreeMem(P);
    raise;
  end;
end;

procedure TMyDataStack.Push(Value: ShortString);
var
  P: PMyData;
begin
  P := AllocMem(SizeOf(TMyData));
  try
    P^.Kind := 2;
    P^.AsString := Value;
    FList.Add(P);
  except
    FreeMem(P);
    raise;
  end;
end;

HTH
TOndrej
0
 
LVL 9

Expert Comment

by:ITugay
ID: 6990247
Hi all,

there is Variant type that able to keep integer, string, double etc.

Here is a sample:

uses
   ..., contnrs, .... // contnrs unit shipped with all of Delphi (standard, prof, ent.)

type

  TSomeData = class(TObject)
    Data: Variant;
  end;

  TSomeStack = class(TObjectList)
    procedure Push(AValue: Variant);
    function Pop: Variant;
  end;

.....

procedure TSomeStack.Push(AValue: Variant);
var
  D: TSomeData;
begin
  D := TSomeData.Create;
  D.Data := AValue;
  Add(D);
end;

function TSomeStack.Pop: Variant;
begin
  if Count > 0 then
  begin
    Result := TSomeData(Items[Count-1]).Data;
    Delete(Count-1);
  end
  else
    raise Exception.Create('stack is empty');    
end;

.....

var
  Stack: TSomeStack;

  S: String;
  I: Integer;
  Z: Double;
begin
  Stack := TSomeStack.Create;
  Stack.Push('12345');
  Stack.Push(12345);
  Stack.Push(123.45);

  Z := Stack.Pop;
  I := Stack.Pop;
  S := Stack.Pop;

  Stack.Free;

end;

----
Igor.
0
 
LVL 14

Expert Comment

by:AvonWyss
ID: 6991230
As long as you're dealing with object referenced, there is no need for "dirty" tricks. Then, it is always possible to "box" data types into objects, which then allows the use of IS and AS operators (just as with any other object type). If you don't want to use TObject descendands as carriers for simple data types (which is the most generic approach), stick to one of the other suggestions here.
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 6991266
procedure TForm1.Button6Click(Sender: TObject);
var
 v:variant;  //this is a great type.
 i:integer;
 b:boolean;
begin
  v:=true;
  i := v;
  v := i+100;
  i := v;
  b := v;
  if b then showmessage(IntToStr(i));

end;
0
 

Author Comment

by:Gamba
ID: 6993442
So many comments! Thank you.
Sorry for late answering, but e-mail-notification in EE
seems not to work correct (I received 4 mails today).

I know the variant type, but the problem indeed is
- as AvonWyss says - to generate copies of objects,
which should have various size and many different
object types.
So I would need the mentioned functions:
  somekindeof_copy(stackcontent,obj);
and
  somekindeof_freemem(stackcontent);
to allocte memory, cause the copies should be modified
without modifying the original object.

0
 
LVL 7

Expert Comment

by:God_Ares
ID: 6993500
procedure TForm1.Button1Click(Sender: TObject);
var a,b : variant;
    i,j:integer;
begin
  i:=100;
  a:=i;
  i:=120;
  j:=a;
  showmessage( IntToStr (j) );
  b:=a;
  a:=i;
  j:=b;
  showmessage( IntToStr (j) );
  j:=a;
  showmessage( IntToStr (j) );
end;

so

function TSomeStack.Pop_copy: Variant;
begin
 if Count > 0 then
 begin
   Result := TSomeData(Items[Count-1]).Data;
 end
 else
   raise Exception.Create('stack is empty');    
end;


object still exsists.

elaborate:
somekindeof_copy(stackcontent : Integer??; obj: Pointer???);

0
 

Author Comment

by:Gamba
ID: 7000644
Sorry, God_Ares, could you explain this a little more?
What is TSomeData().Date.

What does this mean:

object still exsists.

elaborate:
somekindeof_copy(stackcontent : Integer??; obj: Pointer???);

(maybe you could say this in simple words, my English
is not the very best...)

Thanks,

Gamba



0
 
LVL 7

Expert Comment

by:God_Ares
ID: 7005371

>Sorry, God_Ares, could you explain this a little more?
What is TSomeData().Date.

TSomeData(Items[Count-1]).Data;

Cast a variable to an TSomeData  TSomeData has a Data property of the type variant.

>What does this mean:

>object still exsists.
after using pop_copy there will be copy of the top item on the stack. The object on there will still exsist.


>elaborate:
>somekindeof_copy(stackcontent : Integer??; obj: >Pointer???);
what parameters should be given to this function? what is it's goal?


Hope this is more understandable english for you.

Regards
...

0
 

Author Comment

by:Gamba
ID: 7005758
Thank you for explanation.

somekindof_copy should make a copy of an object
(this is stackcontent, the defintiion has an error;
it must be stackcontent:pointer, not integer)
and fill var obj:pointer with the adress of
the new object.

I'm not quite sure about
>>   TSomeData(Items[Count-1]).Data
Will this work for objects or only for
numbers (int, double) and strings?

Gamba


0
 
LVL 7

Accepted Solution

by:
God_Ares earned 150 total points
ID: 7005921
like this?
somekindof_copy(location:integer) : Variant;

usage

push('aa');
push(32);
push(3.2);
push(322);

a := somekindof_copy(1);

a would be 32
0
 

Author Comment

by:Gamba
ID: 7006102
Yes, but also like this:

type class1 = class
              el1 : integer
              el2 : string;
            end;

type class2 = class
              el1 : string;
              el2 : word;
              el3 : double;
            end;

procedure DoSomething;
var cl1:class1;
    cl2:class2;

begin

  cl1 = new class1;
  cl1.el1 := 3;
  cl1.el2 := 'string1';
  cl2.el1 := 'string2;
  cl2.el2 := 12345;

  push(cl1);
  x:=somekindofcopy(1);
  ShowMessage('el1 = ' + inttostr(x.el1));
  ShowMessage('el2 = ' + x.el2);
  pop(cl1);
  push(cl2);
  y:=somekindofcopy(1);
  ShowMessage('el1 = ' + y.el1);
  ShowMessage('el2 = ' + inttostr(y.el2));
  ShowMessage('el3 = ' + floattostr(y.el3));
  pop(cl2);
end;


??


Gamba
0
 

Author Comment

by:Gamba
ID: 7066317
Are there no further comments?
Would it be o.k. for you, if I
would let delete this question?

Gamba
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9004610
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from God_Ares

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses
Course of the Month8 days, 18 hours left to enroll

615 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question