捐助郴维网
感谢您对郴维网的支持,你的支持将是郴维网持续发展的动力!
二维码
×
当前位置:郴维网 >基础知识 > 正文
12 2021.12

Delphi 的内存操作函数(1): 给字符指针分配内存

点击次数:285 更新时间: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安装调试,服务器维护,数据恢复,密码破解,网络布线,网络检修,打印机维修,打印机加碳粉,苹果电脑安装系统,苹果电脑安装双系统,监控安装维护,电脑外包,笔记本电脑维修,餐饮、美容行业软件安装 等。。。。。。
点击次数:285 更新时间:2021-12-12 15:24:49  【打印此页
关键词推荐:郴州电脑城 郴州电脑维修公司 维修电脑公司 郴州软件开发 上门电脑维修 上门安装系统 笔记本电脑维修 郴州打印机维修 打印机加碳粉 电脑安装双系统 苹果电脑双系统 液晶显示器维修 联想笔记本维修 联想笔记本维修电话 戴尔笔记本维修电话 郴州戴尔笔记本维修 戴尔笔记本郴州维修点 华硕笔记本维修点 郴州华硕笔记本维修 郴州笔记本上网维修