[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Difference between address and pointer

Posted on 2004-10-21
11
Medium Priority
?
202 Views
Last Modified: 2010-04-05
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!





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
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 6

Expert Comment

by:vadim_ti
ID: 12373780
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.
0
 
LVL 1

Expert Comment

by:sokpas
ID: 12374376
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.
0
 
LVL 6

Assisted Solution

by:Sergio_Hdez
Sergio_Hdez earned 200 total points
ID: 12378909
As other have pointed, using Laticce: TLattice is not the same as LaticceAddress: ^TLattice, as the first method let you create the Lattice INSIDE the object, while the second forces you to create it and then assign it to the pointer, so you can make it twice with the same Lattice being pointed from 2 pointers.

Also, I would do this when freeing it (in both cases, object or pointer):

LatticeCache.caches[current_ID].Lattice.Free;
LatticeCache.caches[current_ID].Lattice:= Nil;

So you avoid freeing it twice (it does nothing if you try to free it twice) as long as it is not rteferenced by pointers in other objects.
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:reynaerde
ID: 12387682
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;
0
 
LVL 1

Assisted Solution

by:sokpas
sokpas earned 400 total points
ID: 12390249
Wrong,
>  for Teller := 0 to 2 do
>  begin
>    Lattice := TLattice.create(700,700);
>   LatticeCache.caches[Teller].LatticeAddress := @Lattice; <======= Here The address is the same!
>  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?

You just assign a pointer to the address of lattice  wich is the same in both times. So you just have the last object created (and pointed by Lattice) to all the pointers in LatticeCache. you should
 LatticeCache.caches[Teller].LatticeAddress := Lattice^;
The way you do it to be correct.
0
 
LVL 34

Assisted Solution

by:Slick812
Slick812 earned 1400 total points
ID: 12390912
hello  reynaerde, I look your question here and the code in your last comment -

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

and I really thought it should work, it looked like correct pascal syntax to me, however your comment made me try it, and to my suprize, ,  my code did the same as your code (I used a TStringList instead of the TLattice, thinking the TLattice might be wonky). .
I then tried this code, without a FOR loop -

type
  PStringList = ^TStringList;

var
i: Integer;
caches : array of PStringList;
StrL1: TStringList;
begin
SetLength(caches, 5);


StrL1 := TStringList.Create;
caches[0] := @StrL1;
ShowMessage(IntToStr(Integer(@StrL1)));
StrL1 := nil;  // I thought set to nil would cancel the first create
StrL1 := TStringList.Create;
caches[1] := @StrL1;
ShowMessage(IntToStr(Integer(@StrL1)));
  //shows the same ADDY in both Showmessages?

if caches[0] = caches[1] then
  ShowMessage(' pointers Are Equal');
  // showed this message


for i := 0 to 1 do
  caches[i].Free; // access violation here
end;

I could not beleive it, and I can not explain it, I do not remember having this before?
I can not find anything about this in the Delphi Help, but I am not sure where to look in there?


So, (?) It looks like if you repeat an object Creation with the same variable, it does not create a new object, it just replaces the variable with the previous creation object, but I do NOT know anything about this, or any why or how of the object NON-creation.

anyway, here is some code with what I think is more correct delphi syntax -


type
  PStringList = ^TStringList;

var
i: Integer;
caches : array of PStringList;
begin

for i := 0 to 1 do
  begin
  New(caches[i]);
  caches[i]^ := TStringList.Create;
  ShowMessage(IntToStr(Integer(caches[i])));
  end;

this seems to work for me
I am guessing that this is an experiment for you? I think most (at least me) would not use the

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

but I would use

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

actually I would NOT have only the  "Lattice : TLattice;"  in an Object, since it will work by it's self. . . but I guess that there are other things that you will place in this object. . .
0
 

Author Comment

by:reynaerde
ID: 12395225
@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.
0
 

Author Comment

by:reynaerde
ID: 12395229
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;

:)
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 1400 total points
ID: 12397145
LatticeCache.caches[Teller].LatticeAddress^ := Lattice;
the above seems Incorrect to me, maybe it should be -
 LatticeCache.caches[Teller].LatticeAddress^ := TLattice.Create( );

this is a short comment, since the whole "Pointer"  and  "TObject" and Delphi memory workings are NOT simple and straight-forward (as you seem to have gathered by now. . . All variable size "variables" like a String and some TObject are different than fixed size variables like an Integer, TPoint, or TRect, Delphi handles the memory assignments for all TObjects and Strings, when you call

StrL1 := TStringList.Create;

the memory for a StringList "Object" is allocated and the memory positions for constansts, functions and variables are placed in the new string list TObject, , so I guess my view is that the StrL1 is a Pointer to a Pointer after you call the Create. . .

so you call -

new(LatticeCache.caches[Teller].LatticeAddress);

and this will get memory for the other pointer, there is already a "Pointer" memory (4 bytes) assigned for the "LatticeAddress"
if you do not call new( ) then there is NO memory allocated for the Object pointer

you will need to Dereference the LatticeAddress when you use it with create, Because it is a memory address (pointer) , , and the create should return the second mem address for the "Object"

LatticeCache.caches[Teller].LatticeAddress^ :=  TLattice.Create;

but there is more to the TObject, than just the other pointer

and as I see it

LatticeAddress : ^TLattice;

and

Lattice : TLattice;

are NOT the same, although with Delphi you can use the LatticeAddress as a TLattice in many cases (but not all), I would only use the ^TLattice if there was some code that FORCED me to use a Pointer type, other wize I would use the standard way with a TLattice, because you can most always use  @Lattice1  if you just got to have a pointer
0
 
LVL 34

Expert Comment

by:Slick812
ID: 12397216
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;
0
 
LVL 34

Assisted Solution

by:Slick812
Slick812 earned 1400 total points
ID: 12397228

TCell = class(TObject)
  status : cell_status;
  to_update : cell_status;
  lifetime: word;
  resist: byte;
  activated: bool;
  constructor create();
end;

and I really wonder about why you placed this in and object, you do not have ANY functions or procedures in this object, I think it is more effiecient to just use a Record, maybe -

TCell = record
  status : cell_status;
  to_update : cell_status;
  lifetime: word;
  resist: byte;
  activated: bool;
  end;
0

Featured Post

Tech or Treat! - Giveaway

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

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

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
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…
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…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

650 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