IceCold
IceCold

Reputation: 21184

Array of (pointers to a record)

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.

Upvotes: 5

Views: 3600

Answers (1)

Rob Kennedy
Rob Kennedy

Reputation: 163317

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.

Upvotes: 6

Related Questions