马上能想到的函数有:
给字符指针(PChar、PWideChar、PAnsiChar)分配内存, 最佳选择是: StrAlloc.
StrAlloc 虽然最终也是调用了 GetMem, 但 StrAlloc 会在指针前面添加 Delphi 需要的 4 个管理字节(记录长度).
StrAlloc 分配的内存, 用 StrDispose 释放, 用 StrBufSize 获取大小.
用 FreeMem 释放可以吗? 这样会少释放 4 个字节.
这种类型的指针一般用于 API 函数的参数, 譬如获取窗口标题:
StrAlloc 根据不同的参数(PWideChar、PAnsiChar)分别重载调用了 WideStrAlloc、AnsiStrAlloc, 所以我们也可以直接使用这两个函数(这也需要用 StrDispose 释放), 不过使用它们的必要性不大; 用 StrAlloc 指定好参数类型即可.
给字符指针分配内存其他方法也挺方便, 譬如:
数组的内存不是我们自己申请的, 系统会自动释放; 记住: 只要是手动申请的内存一定要手动释放.
我们给字符指针申请内存主要是为了在 API 中接受数据, 如果我们要直接赋给常量值, 系统会自动分配内存的, 譬如:
当然我们也可以用这种办法申请内存, 就是笨了点, 譬如:
如果在 API 函数需要的字符指针是为了输入, 当然也不需要申请内存, 譬如:
跑题了...到现在已用到了 StrAlloc、StrDispose、WideStrAlloc、AnsiStrAlloc、StrBufSize 几个函数.
还有 NewStr、DisposeStr、StrNew、StrDispose 也貌似有点关系.
先说 NewStr 和 DisposeStr(它们是一对);
NewStr 是根据 AnsiString 再新建一个 PAnsiString, 不过这是为兼容而存在的, Delphi 已不提倡使用了.
不再提倡使用的函数都缀以 deprecated 标识, 并在代码提示中用灰色显示.
其实用 @ 即可获取字符串指针, 当然根本用不着它们.
还有个 StrNew; StrNew 可以再制一个相同的字符指针, 譬如:
不过 StrNew 存在的意义也不大, 我们可以更简单地完成上面的操作:
说来说去, 好像只有 StrAlloc 是我们值得我们记忆的?
还有一对非常重要的相关函数: GlobalAllocPtr、GlobalFreePtr; 它们的功能是上面这些都不可替代的!
GlobalAllocPtr 和 GlobalFreePtr 是对系统函数: GlobalAlloc、GlobalFree 的简化, 之所以说它们重要, 只是因为它们可以跨进程操作; 不过 GlobalAllocPtr 是给无类型指针(Pointer)分配内存, 当然就不仅仅用于字符指针了. 还是到后面专题再做例子吧.
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 := '万一的 Delphi 博客'; ShowMessage(p); {万一的 Delphi 博客} 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 := '万一的 Delphi 博客'; 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)分配内存, 当然就不仅仅用于字符指针了. 还是到后面专题再做例子吧.
分类:
Delphi 内存与指针
, 字符串操作及相关函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧