2009-09-08 44 views
5

我想要創建一堆記錄(RWell)並按特定順序將它們存儲在一個數組中。然後我想創建一個新的數組(不同的佈局)並重新排列它中的記錄。 當然,我不想在RAM中複製數據,所以我儘管在第二個數組中我應該把指針指向第一個數組中的記錄。但是,我不能那樣做。任何人都可以知道下面的代碼有什麼問題? 感謝數組(指向記錄的指針)

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; 

羅布K.

解決
+1

您將獲得關於添加到動態數組末尾的技巧的評論。它可能效率低下,可能會碎片化。你最好將數組的大小設置爲你需要的大小,然後將值分配給下一個未分配的元素。另一種選擇是使用'TList',它非常擅長存儲指針。從Delphi 2009開始,它甚至可能是類型安全的,如TList 。 – 2009-09-08 19:26:30

+0

我不知道該數組在運行時的大小。而且我知道這是不是最佳的我設定它的長度。但它非常小(低於600個條目),所以碎片會很小。我現在不打擾改變它。感謝您的建議:) – Ampere 2009-09-08 20:01:37

+0

我同意在這裏使用列表更好。 – 2009-09-08 20:39:40

回答

6

在你AddWell功能,你按值傳遞記錄。這意味着該函數獲得實際參數的副本。你正在存儲一個指向形式參數的指針,它可能只是函數本地堆棧上的一個位置。

如果你想有一個指針好,然後將指針傳遞給一個很好:

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

另一種選擇是由常量的值通過備案。對於記錄來說,這意味着實際參數作爲參考傳遞。指向正式參數的指針也是指向實際參數的指針:

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

雖然,我不會真的依賴這個。當你想要指針時,傳遞指針。有些人試圖避免在代碼中使用指針,但他們沒有什麼可害怕的。

+1

AFAIK const不保證強制通過引用傳遞,所以我不會在這裏依賴它。 – 2009-09-08 19:26:26

+0

第一個沒有工作:不兼容的類型PWell和RWell。 第二個工作,但在該過程內,我有代碼,需要修改AWell,現在是隻讀(常量)。 (對不起,我沒有提供完整的代碼來使我的問題易於閱讀/理解)。 – Ampere 2009-09-08 19:54:33

+0

第一個沒有工作,因爲你沒有改變*調用者*。當你調用這個函數時,你需要傳遞一個指針:'AddWell(@WellMX [2,3])'。 – 2009-09-08 20:15:53