5 Stimmen

Array von (Zeigern auf einen Datensatz)

Ich möchte eine Reihe von Datensätzen (RWell) erstellen und in einem Array in einer bestimmten Reihenfolge speichern. Dann möchte ich ein neues Array (anderes Layout) erstellen und die Datensätze darin neu anordnen. Natürlich möchte ich keine Daten im RAM duplizieren, daher dachte ich, dass ich im zweiten Array Zeiger auf die Datensätze im ersten Array setzen sollte. Allerdings kann ich das nicht tun. Kann mir jemand sagen, was mit dem unten stehenden Code falsch ist? Dank

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 
  { Sollte ich WellXM hier initialisieren? }
  { Beachten: WellXM ist ein statisches Array! }

  andere Sachen
end;

var Wells: array of PWell;
procedure TClass2.AddWell(aWell: RWell);
begin
 aWell.Stuff:= stuff; {aWell kann nicht nur lesend sein, weil ich es hier ändern muss}

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

procedure TClass3.DisplayWell;
var CurWell: RWell;
begin
 CurWell:= CurPrimer.Wells[iCurWell]^;       <--- Problem (aber im Debugger ist die Adresse korrekt)
end;

Gelöst von Rob K.

6voto

Rob Kennedy Punkte 158781

In Ihrer AddWell-Funktion übergeben Sie das Record by value. Das bedeutet, die Funktion erhält eine Kopie des tatsächlichen Parameters. Sie speichern einen Zeiger auf den formalen Parameter, welcher wahrscheinlich nur ein Speicherort im lokalen Stack der Funktion ist.

Wenn Sie einen Zeiger auf ein Bohrloch wollen, dann übergeben Sie einen Zeiger auf ein Bohrloch:

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

Eine weitere Option ist, das Record als const value zu übergeben. Für Records bedeutet das, dass der tatsächliche Parameter als Referenz übergeben wird. Ein Zeiger auf den formalen Parameter ist auch ein Zeiger auf den tatsächlichen Parameter:

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

Darauf würde ich mich allerdings nicht wirklich verlassen. Wenn Sie Zeiger wollen, übergeben Sie Zeiger. Einige Leute versuchen, Zeiger in ihrem Code zu vermeiden, aber sie sind nichts, vor dem man Angst haben müsste.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X