Delphi使用PShortString指針

今天學習的時候,看到RTTI結構裏用了蠻多PShortString指針,由於ShortString比較特殊,所以操作PShortString的簡單demo鞏固一下

值得注意的是:
1.平常項目中一般不會使用PShortString,一般直接使用PChar操作內存,也很少在一個結構體中添加變長的成員變量。

//推薦做法,Desc記得要GetMem()/FreeMem()
PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID : Integer;
    Desc : PChar;
  end;

2.如果實在需要在結構體中添加變長的成員變量,可以使用變長數組代替(array of Type),請務必要放在最後

//推薦做法
PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID : Integer;
    Name : array[0..127] of char;
    Reserved : array of Integer;
  end;
  
//糟糕的做法
PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID : Integer;
    Reserved : array of Integer;		//萬一該不定長數組長度變化了,後面的成員地址全部要挪動
    Name : array[0..127] of char;
  end;

3.如果結構體中需要不定長的字符串成員,可以使用字符數組代替,數組長度可設大一點,如:array[0…1023] of char。

PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID : Integer;
    Name : array[0..1023] of char;	//設置大一點沒關係
    Desc : PChar;
  end;

4.一般情況下,不會在結構體中定義string類型的成員

//糟糕的做法
TMyRecord = record
	...
	Name : String;	
end

以上的建議可以避免繁瑣的內存管理。

type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID : Integer;
    Name : ShortString;
    Desc : PShortString;
  end;
  
...

procedure TForm2.btn1Click(Sender: TObject);
var
  pMy : PMyRecord;
  index : Integer;
  tempStr : PShortString;
begin
  New(pMy);
  index := 0;
  FillChar(pMy^, SizeOf(TMyRecord), #0);
  GetMem(pMy^.Desc, 1);   //只申請一個空間
  FillChar(pMy.Desc^, SizeOf(pMy.Desc^), #0);
  pMy^.ID := 1;
  pMy^.Name := 'test1abcd';
  pMy^.Desc^ := 'ggaaddggkkll'; //12個字母

  Move(pMy^.ID, FPChar[0], SizeOf(pMy^.ID));

  index := index + SizeOf(pMy^.ID);
  //shortstring第0位保存了字符串的長度,所以這裏要+1
  Move(pMy^.Name, FPChar[index], Length(pMy^.Name) + 1);

  index := index + Length(pMy^.Name) + 1;
  Move(pMy.Desc^, FPChar[index], Length(pMy^.Desc^) + 1);

  //print
  index := SizeOf(Integer); 
  tempStr := PShortString(@FPChar[index]);
  ShowMessage(tempStr^);

  index := index + Length(pMy^.Name) + 1;
  tempStr := PShortString(@FPChar[index]);
  ShowMessage(tempStr^);

  FreeMem(pMy^.Desc);
  Dispose(pMy);
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  GetMem(FPChar, 1000);
  FillChar(FPChar^, SizeOf(FPChar^), #0);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  FreeMem(FPChar);
end;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章