tags:

views:

135

answers:

1

Hi. I want to create a bunch of records (RWell) and to store them in an array in a certain order. Then I want to create a new array (different layout) and rearange the records in it. Of course, I don't want to duplicate data in RAM so I though that in the second array I should put pointers to the records in the first array. However, I can't do that. Anybody can tell what's wrong with the code below? Thanks

Type 
  RWell= record                                 
    x: string;  
    i: integer;
  end;

  PWell= ^RWell;

  RWellArray= Array[0..12, 0..8] of RWell;    


procedure TClass1.CreateWells
var 
  WellMX: RWellArray;
begin 
  { should I initialize the WellXM here? }
  { note: WellXM is a static array! }

  other stuff
end;



var Wells: array of PWell;
procedure TClass2.AddWell(aWell: RWell);
begin
 aWell.Stuff:= stuff; {aWell cannot be readonly because I need to change it here}

 SetLength(Wells, Length(Wells)+ 1);  { reserve memory } 
 Wells[High(Wells)]:= @aWell;
end;



procedure TClass3.DisplayWell;
var CurWell: RWell;
begin
 CurWell:= CurPrimer.Wells[iCurWell]^;       <--- AV here (but in debugger the address is correct)
end;


Solved by Rob K.

+4  A: 

In your AddWell function, you're passing the record by value. That means the function gets a copy of the actual parameter. You're storing a pointer to the formal parameter, which is probably just a location on the local stack of the function.

If you want a pointer to a well, then pass a pointer to a well:

procedure AddWell(AWell: PWell);
begin
  SetLength(Wells, Length(Wells) + 1);
  Wells[High(Wells)] := AWell;
end;

Another option is to pass the record by const value. For records, this means the actual parameter is passed as a reference. A pointer to the formal parameter is also a pointer to the actual parameter:

procedure AddWell(const AWell: RWell);
begin
  SetLength(Wells, Length(Wells) + 1);
  Wells[High(Wells)] := @AWell;
end;

I wouldn't really rely on that, though. When you want pointers, pass pointers. Some people try to avoid pointers in their code, but they're nothing to be afraid of.

Rob Kennedy
AFAIK const isn't guaranteed to enforce passing by reference, so I wouldn't rely on it here.
Ulrich Gerhardt
First one didn't worked: Incompatible types PWell and RWell.The second one worked BUT inside that procedure I have code that needs to modify AWell, which now is read-only (const).(sorry, I didn't provided the full code to make my question easy to read/understand).
Altar
The first one didn't work because you didn't change the *caller*. You need to pass a pointer when you call the function: `AddWell(@WellMX[2, 3])`.
Rob Kennedy
You are right. It worked. Thanks a lot for your great wisdom! ---------------- Answer marked as "Accepted".
Altar