[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Short question about copying array contents and pointer assignment

Posted on 2004-10-26
5
Medium Priority
?
176 Views
Last Modified: 2010-04-05
Considering the following:

TCell = packed record
  status : cell_status;
  to_update : cell_status;
  lifetime: word;
  resist: byte;
  activated: boolean;
end;

type cell_pointer = ^TCell;

TMargolusBlock = packed record
  cell : array[0..3] of cell_pointer;
end;

TMargolusArray = class(TObject)
  mblock : array of array of TMargolusBlock;
  constructor create(size : Integer);
  destructor Destroy;
    override;
end;


currentMargolusArray : TMargolusArray;


Then:

currentMargolusArray := MargolusArrayA;

doesn't work, I just get a TMargolusArray object with an array filles with nils.
How can I get the contents of MargolusArrayA in currentMargolusArray ? Or do I really need to copy the whole thing?
(like: for teller := 0 to ...: currentMargolusArray.cell[0] := MargolusArrayA.cell[0] etc..)

Furthermore, a bit related, what is the difference between:

type cell_pointer = ^TCell;
cpointer : cell_pointer;
cell : Tcell;

cpointer := @cell;

and

cpointer^ := cell;??
0
Comment
Question by:reynaerde
[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
  • 2
  • 2
5 Comments
 
LVL 7

Assisted Solution

by:LRHGuy
LRHGuy earned 1300 total points
ID: 12414794
You just cannot simply "copy" an object.

But you can create a method to do so!

procedure tMargolusArray.CopyFrom(aOrig:tMargolusArray);
begin
  SetLength(MBlock,aOrig.dimension1,aOrig,dimension2);  // get array size from original object
  Move(aOrig.MBlock,MBlock,sizeof(aOrig.MBlock)); // copy array
end;

This puts the address of cell into cpointer:

cpointer := @cell;

This puts the contents of cell into the tcell referenced by cpointer:

cpointer^ := cell;??
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12414875
The only way: (Not tested in compiler)

var
  I:Integer;
begin
  SetLength(Target, Length(Source));
  for I := Low(Source) to High(Source) do Target[I] := Source[I];
end;

And if the array contains pointers to objects or records, then those things aren't copied either, just the references.

The thing you have to keep in mind is the difference between the actual data and references to data. For a better performance, you should just keep copying those references. Because copying data costs a little bit of time and the more data you have to copy, the more performance you'll lose. Do you really need to copy those arrays?
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12414903
cpointer := @cell;
Here, cpointer is told to point to a reference pointer that is pointing at cell.

cpointer^ := cell;
Here, the reference that cpointer is pointing to is changed to reference to cell.

Pointers to pointers can make life real complicated. :-)
0
 
LVL 7

Accepted Solution

by:
LRHGuy earned 1300 total points
ID: 12416117
What Workshop_Alex indicates is true...if TCell is an object...but in your example, tcell is a record, so be careful!

type
  tcell=record  
  cellptr=^tcell   // pointer to a record

var
  cell:tcell;  //the actual record
  cp:cellptr;

  cp:=@tcell  //cp points to actual record
 
type
  tcell=class
  cellptr=^tcell   //pointer to a pointer

var
  cell:tcell;  //pointer to class object
  cp:cellptr;

  cp:=@tcell; //cp points to a pointer that points to the actual object data

As Workshop said, it can be complicated!
 
0
 
LVL 34

Assisted Solution

by:Slick812
Slick812 earned 300 total points
ID: 12416158
hi again, , first I wonder about having a Record with only ONE elements as your -

TMargolusBlock = packed record
  cell : array[0..3] of cell_pointer;
end;

 this seems kind of "not needed" to me, since a Record was made to hold more then ONE element, so I changed it to a type -

type
  cellMB = array[0..3] of cell_pointer;

I also wondered why you always want to use a pointer to something instead of the something that is pointed to, you use a "cell_pointer" instead of a "TCell", but for me, it seems this would not have any advantage, and would just mean I would have to write more code to initialize and free this cell_pointer, so I changed it to a TCell -

type
  cellMB = array[0..3] of TCell;

  TMargolusArray = class
    FSize: Integer;
    mblock : array of array of CellMB;
    procedure Assign(MArray: TMargolusArray);
    constructor create(size: Integer);
    destructor Destroy; override;
  end;

 - - - - - - - -  - - - -  - - -

I also had to change the class  TMargolusArray , as seen above

 - - - - - - - - - - - - - - - -  - - - -

for your
currentMargolusArray := MargolusArrayA;
doesn't work question. . .

when you use the
 :=
with a TObject, it DOES NOT  create a new TObject, the  currentMargolusArray  will be one and the same as  MargolusArrayA, (the object pointer value is ALL that is copied, no object elements are involved), ,  if you free one of them the other is also gone (because the other is the same thing), as in the code below -



procedure TForm1.sbut_ObjectAsgnClick(Sender: TObject);
var
MArray1, curMArray: TMargolusArray;
begin
MArray1 := TMargolusArray.Create(6);
Marray1.mBlock[5,5,3].lifetime := 12345;
curMArray := MArray1;
// the line above does not create a separate TMargolusArray
// it just copy the Object Pointer, so now they are the same TMargolusArray
ShowMessage(IntToStr(curMArray.mBlock[5,5,3].lifetime));
FreeAndNil(MArray1); // this also frees the curMArray, since they are the same
ShowMessage(IntToStr(curMArray.mBlock[5,5,3].lifetime));
// I get an access violation in the line above
end;


 - - - - - - -  - - - - -  - - - - - -

and Yes, you will really need to copy every array element from one to the  other, here is my code for the  TMargolusArray  , I have added an Assign procedure -

constructor TMargolusArray.create(size: Integer);
begin
FSize := size;
SetLength(mblock, Size, Size);
mblock[0,0,0].status := H; // just for looks, not know your initialize
end;

destructor TMargolusArray.Destroy;
begin
SetLength(mblock, 0,0);
end;

procedure TMargolusArray.Assign(MArray: TMargolusArray);
var
i, j, k: Integer;
begin
if (not Assigned(MArray)) then Exit;
FSize := MArray.FSize;
SetLength(mblock, FSize, FSize);

for i := 0 to FSize-1 do
  for j := 0 to FSize-1 do
    for k := 0 to 3 do
      mblock[i,j,k] := MArray.mblock[i,j,k];
end;

the Assign method is in to the TPersistent Class and not in the TObject class, but I have added it here.
below is some button click code for this -


procedure TForm1.sbut_ObjectAsgnClick(Sender: TObject);
var
MArray1, curMArray: TMargolusArray;
begin
MArray1 := TMargolusArray.Create(6);
Marray1.mBlock[5,5,3].lifetime := 12345;
curMArray := TMargolusArray.Create(Marray1.FSize);
ShowMessage(IntToStr(curMArray.mBlock[5,5,3].lifetime));
curMArray.Assign(MArray1);
FreeAndNil(MArray1);
ShowMessage(IntToStr(curMArray.mBlock[5,5,3].lifetime));
// show the same number in the Marray1
FreeAndNil(curMArray);
end;


- - - - - - - - - - - - - - - - - -  - - - -  - - - - -
maybe some ides from this
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

649 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