捐助郴維網
感謝您對郴維網的支持,你的支持將是郴維網持續發展的動力!
二維碼
×
當前位置:郴維網 >基礎知識 > 正文
12 2021.12

Delphi 的內存操作函數(1): 給字符指針分配內存

點擊次數:276 更新時間:2021-12-12 15:24:49  【打印此頁

馬上能想到的函數有:

分配 釋放 最佳適用對象
GetMem
AllocMem
ReallocMem
FreeMem 給無類型指針分配內存
GetMemory
ReallocMemory
FreeMemory 給無類型指針分配內存(推薦)
New Dispose 給已知大小的指針分配內存
NewStr DisposeStr 字符(已棄用)
StrNew
StrAlloc
StrDispose 字符(推薦)
GlobalAllocPtr GlobalFreePtr 跨進程的內存分配
WideStrAlloc
AnsiStrAlloc
StrDispose 字符

Move

MoveMemory

CopyMemory

ZeroMemory

FillMemory

FillChar

 

StrBufSize

 


給字符指針(PChar、PWideChar、PAnsiChar)分配內存, 最佳選擇是: StrAlloc.

StrAlloc 雖然最終也是調用了 GetMem, 但 StrAlloc 會在指針前面添加 Delphi 需要的 4 個管理字節(記錄長度).

StrAlloc 分配的內存, 用 StrDispose 釋放, 用 StrBufSize 獲取大小.

用 FreeMem 釋放可以嗎? 這樣會少釋放 4 個字節.

這種類型的指針一般用于 API 函數的參數, 譬如獲取窗口標題:

var
  p: PChar;
begin
  p := StrAlloc(256);
  GetWindowText(Handle, p, StrBufSize(p));
  ShowMessage(p); {Form1}
  StrDispose(p);
end;

 

StrAlloc 根據不同的參數(PWideChar、PAnsiChar)分別重載調用了 WideStrAlloc、AnsiStrAlloc, 所以我們也可以直接使用這兩個函數(這也需要用 StrDispose 釋放), 不過使用它們的必要性不大; 用 StrAlloc 指定好參數類型即可.

給字符指針分配內存其他方法也挺方便, 譬如:

//  獲取 WINDOWS 所在目錄
var
  buf: array[0..MAX_PATH] of Char;
begin
  GetWindowsDirectory(buf, Length(buf));
  ShowMessage(buf); {C:\WINDOWS}
end;

數組的內存不是我們自己申請的, 系統會自動釋放; 記住: 只要是手動申請的內存一定要手動釋放.

我們給字符指針申請內存主要是為了在 API 中接受數據, 如果我們要直接賦給常量值, 系統會自動分配內存的, 譬如:

var
  p: PChar;
begin
  p := '郴維網 - 1118pc.com';
  ShowMessage(p); {郴維網 - 1118pc.com}
end;

當然我們也可以用這種辦法申請內存, 就是笨了點, 譬如:

// 獲取系統目錄
var
  p: PChar;
begin
  p := PChar(StringOfChar(Char(0), 256)); {反復一個空字符 256 次成一個字符串, 然后轉為 PChar}
  GetSystemDirectory(p, StrBufSize(p));
  ShowMessage(p); {C:\WINDOWS\system32}
end;

如果在 API 函數需要的字符指針是為了輸入, 當然也不需要申請內存, 譬如:

//  設置窗口標題
var
  p: PChar;
begin
  p := '窗口新標題';
  SetWindowText(Handle, p);
end;

//  也可以直接給常量
begin
  MessageBox(Handle, '提示信息', '標題', MB_OK);
end;

//  如果是給字符串的變量或常量, 則需要轉換一下
var
  str: string;
begin
  str := '郴維網 - 1118pc.com';
  TextOut(Canvas.Handle, 10, 10, PChar(str), Length(str));
  {在窗體上輸出文字, 此代碼不能在 OnCreate 事件中}
end;

跑題了...到現在已用到了 StrAlloc、StrDispose、WideStrAlloc、AnsiStrAlloc、StrBufSize 幾個函數.

還有 NewStr、DisposeStr、StrNew、StrDispose 也貌似有點關系.

先說 NewStr 和 DisposeStr(它們是一對);

NewStr 是根據 AnsiString 再新建一個 PAnsiString, 不過這是為兼容而存在的, Delphi 已不提倡使用了.

不再提倡使用的函數都綴以 deprecated 標識, 并在代碼提示中用灰色顯示.

其實用 @ 即可獲取字符串指針, 當然根本用不著它們.

還有個 StrNew; StrNew 可以再制一個相同的字符指針, 譬如:

var
  p1,p2: PChar;
begin
  p1 := 'Delphi';

  p2 := StrNew(p1);
  ShowMessageFmt('%s, %s', [p1, p2]); {Delphi, Delphi}

  p1 := '2009';
  ShowMessageFmt('%s, %s', [p1, p2]); {2009, Delphi}

  StrDispose(p2); {釋放自己申請的}
end;

不過 StrNew 存在的意義也不大, 我們可以更簡單地完成上面的操作:

var
  p1,p2: PChar;
begin
  p1 := 'Delphi';
  p2 := p1;
  ShowMessageFmt('%s, %s', [p1, p2]); {Delphi, Delphi}
  p1 := '2009';
  ShowMessageFmt('%s, %s', [p1, p2]); {2009, Delphi}
end;

說來說去, 好像只有 StrAlloc 是我們值得我們記憶的?

還有一對非常重要的相關函數: GlobalAllocPtr、GlobalFreePtr; 它們的功能是上面這些都不可替代的!

GlobalAllocPtr 和 GlobalFreePtr 是對系統函數: GlobalAlloc、GlobalFree 的簡化, 之所以說它們重要, 只是因為它們可以跨進程操作; 不過 GlobalAllocPtr 是給無類型指針(Pointer)分配內存, 當然就不僅僅用于字符指針了. 還是到后面專題再做例子吧.

Tips
郴維網為您提供各類專業服務:
軟件開發,電腦配件銷售,WIFI路由器銷售,上門電腦維修,上門安裝系統,系統安裝,軟、硬件安裝,電腦除塵清灰,顯示器維修,WIFI安裝調試,服務器維護,數據恢復,密碼破解,網絡布線,網絡檢修,打印機維修,打印機加碳粉,蘋果電腦安裝系統,蘋果電腦安裝雙系統,監控安裝維護,電腦外包,筆記本電腦維修,餐飲、美容行業軟件安裝 等。。。。。。
點擊次數:276 更新時間:2021-12-12 15:24:49  【打印此頁
關鍵詞推薦:郴州電腦城 郴州電腦維修公司 維修電腦公司 郴州軟件開發 上門電腦維修 上門安裝系統 筆記本電腦維修 郴州打印機維修 打印機加碳粉 電腦安裝雙系統 蘋果電腦雙系統 液晶顯示器維修 聯想筆記本維修 聯想筆記本維修電話 戴爾筆記本維修電話 郴州戴爾筆記本維修 戴爾筆記本郴州維修點 華碩筆記本維修點 郴州華碩筆記本維修 郴州筆記本上網維修
免费A级毛片无码A∨免费软件