Delphi 的内存操作函数(1): 给字符指针分配内存
2008-11-08 12:14
543 查看
马上能想到的函数有:
给字符指针(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 的内存操作函数(1): 给字符指针分配内存
- Delphi 的内存操作函数(1): 给字符指针分配内存
- Delphi 的内存操作函数(1): 给字符指针分配内存
- Delphi 的内存操作函数(1): 给字符指针分配内存
- Delphi 的内存操作函数(1): 给字符指针分配内存
- Delphi 的内存操作函数(1): 给字符指针分配内存( 给字符指针(PChar、PWideChar、PAnsiChar)分配内存最佳的选择是StrAlloc。分配内存的时候会对字符串进行初始化)
- Delphi 的内存操作函数(3): 给结构体指针分配内存
- Delphi 的内存操作函数(3): 给结构体指针分配内存
- Delphi 的内存操作函数(3): 给结构体指针分配内存
- Delphi 的内存操作函数(3): 给结构体指针分配内存
- Delphi 的内存操作函数(2): 给数组指针分配内存
- Delphi 给字符指针分配内存
- [Delphi]内存分配和释放 内存操作函数(4): 清空与填充内存
- 习题 8.19(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- delphi 给字符指针分配内存
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- Delphi 字符指针分配内存
- 终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good
- 内存的堆分配和栈分配 & 字符数组,字符指针,Sizeof总结