Link to home
Start Free TrialLog in
Avatar of reynaerde
reynaerde

asked on

Difference between address and pointer

Say I have the following:

TCachedData = class(TObject)
  LatticeAddress : ^TLattice;
  constructor create();
end;

TCachedDataArray = class(TObject)
  caches : array of TCachedData;
  constructor create(size : Integer);

constructor TCachedData.create();
begin
  inherited;
  self.LatticeAddress := nil;
end;

constructor TCachedDataArray.create(size : Integer);
var
  Teller : Integer;
begin
  setlength(caches, size+1);
  for Teller := 0 to size do
  begin
    self.caches[Teller] := TCachedData.create;
  end;
end;

LatticeCache := TCachedDataArray.create(10);

And I use
Lattice := TLattice.create(.....)
LatticeCache.caches[current_ID].LatticeAddress := @Lattice;

What would be the difference if I was using:

TCachedData = class(TObject)
  LatticeAddress : TLattice;
  constructor create();
end;

 and

LatticeCache.caches[current_ID].LatticeAddress := Lattice;

instead?

Because I keep getting some errors when I try to do

LatticeCache.caches[current_ID].LatticeAddress.Free();

later on.

When I execute the following:

LatticeCache.caches[current_ID].LatticeAddress := Lattice;
LatticeCache.caches[current_ID].LatticeAddress.Free();

it works fine, but when I try to free a particular array element
(LatticeCache.caches[specific_ID_later_on].LatticeAddress.Free(); I get some errors. (this always happens the 2nd time I try to free any particular element, the first one works fine).

This could be due to some error in the code in the 'Lattice' part, but I just want to be sure I'm not making any mistakes here.
Help much appreciated!





Avatar of vadim_ti
vadim_ti

see, first of all there is no differrence between

TCachedData = class(TObject)
  LatticeAddress : ^TLattice;
  constructor create();
end;

and

TCachedData = class(TObject)
  Lattice : TLattice;
  constructor create();
end;

in any case Lattice will save pointer to TLattice object

now if Lattice is only member of TCachedData, may be you can use something
like this

TCachedData = class(TObject)
  constructor create();
end;

TLattice = class(TCachedData)
end;

TSomethingElse = class(TCachedData)
end;

now you can use
  LatticeArray[i] := TLattice.Create(nil);

i also do not think you should use TCachedArray class,
may be simpler is to use TList or TCollection class


it may make things simpler.
It seems that you have a problem not directly related to the code you just posted.
Does each array element have its own Lattice? Is it possible to create once a lattice object and then assign it to 2 or more LatticeCache.caches? If so freeing 2nd time the same object is trouble.
for instance
LatticeCache.caches[current_ID].LatticeAddress := Lattice;
LatticeCache.caches[current_ID+2].LatticeAddress := Lattice;

LatticeCache.caches[current_ID].LatticeAddress.Free();
LatticeCache.caches[current_ID+2].LatticeAddress.Free();

should produce error.
SOLUTION
Avatar of Sergio_Hdez
Sergio_Hdez

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of reynaerde

ASKER

Well, thanks for your advices, but still I'm having the same problem. I tried debugging some more and think I have pinpointed the problem, but I don't understand what is happening. Consider the following:

LatticeCache := TCachedDataArray.create(5);

  for Teller := 0 to 2 do
  begin
    Lattice := TLattice.create(700,700);
    LatticeCache.caches[Teller].LatticeAddress := @Lattice;
  end;

  showmessage('All created');

  if LatticeCache.caches[0].LatticeAddress = LatticeCache.caches[1].LatticeAddress then
    showmessage('hey!');

Am I comparing the 2 addresses here? If so, they are the same, which is strange because I called  Lattice := TLattice.create(700,700); twice..right?
Maybe I am getting a pointer to the address of the Lattice pointer? If so, how can I get the address of where Lattice is pointing TO?
It would, however, explain why I get an error when I execute the following(on the second iteration):

  for Teller := 0 to 2 do
  begin
    showmessage('Freeing: '+inttostr(Teller));
    LatticeCache.caches[Teller].LatticeAddress.Free();
  end;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@sokpas:
Your code gives a compilation error since I'm assigning the dereferenced value of Lattice to a pointer type(LatticeAddress : ^TLattice;)
What I figured myself(and I think this is what you were trying to say) is:
Lattice is a pointer, which points to a different location each time BUT @Lattice is pointing to the address of the pointer itself, thus Lattice^ just is a dereference to the last object assigned to it.

@slick812:
Your way works for me too, but still it seems strange to me:

I. new(LatticeCache.caches[Teller].LatticeAddress);
II. LatticeCache.caches[Teller].LatticeAddress^ := Lattice;

So, now I'm allocating memory for a pointer in <I> and then assigning the Lattice object to the dereferenced value of
LatticeCache.caches[Teller].LatticeAddress in <II>.. quite confusing to me...!!?!


And yes, you are right, the TCachedData holds some other objects but I left them out to simplify the code.
It is sort of an experiment, but in my mind it seemed the most logical thing to do, since I already had TLattice in place and later on needed to keep some of these objects. And to my understanding, Lattice IS in fact a pointer to the memory with the TLattice object. Basically what I do is:

- I am creating an object 'Lattice' on which I run some procedures. I then need to store that for later retrieval and repeat the same process with a new Lattice.
- In step 2 I select the stored Lattices I need and dispose of the rest. Then repeat these steps.

Anyways, the next problem is with the memory amounts I need which seem abnormally large to me, but I'm creating a new question for that.
You will both get points, I just don't want to close this question yet since I'd really like to know the logic behind:

I. new(LatticeCache.caches[Teller].LatticeAddress);
II. LatticeCache.caches[Teller].LatticeAddress^ := Lattice;

:)
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I looked at your other question just a little, and I beleive you may not use correct syntax with -

 for Teller1 := 0 to Dimensie1 + (2*bufferzone -1) do
    begin // vul lattice 1e dimensie
      for Teller2 := 0 to Dimensie2 + (2*bufferzone -1) do  // vul lattice 2e dimensie
      begin
        Temp_Cell := TCell.create();
        self.cell[Teller1,Teller2] := Temp_Cell;
      end; // einde vul lattice 2e dimensie
    end; // einde vul lattice 1e dimensie
end;


you might should Leave OUT the  Temp_Cell  variable and try this

 for Teller1 := 0 to Dimensie1 + (2*bufferzone -1) do
    begin // vul lattice 1e dimensie
      for Teller2 := 0 to Dimensie2 + (2*bufferzone -1) do  // vul lattice 2e dimensie
      begin
        self.cell[Teller1,Teller2] := TCell.create();
      end; // einde vul lattice 2e dimensie
    end; // einde vul lattice 1e dimensie
end;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial