function IsValidMemPtr(Ptr: Pointer): Boolean;
var
p: PInteger;
begin
p := Pointer(Integer(Ptr)-4);
result := (Cardinal(Ptr) > $FFFF) and not IsBadReadPtr(p, 8) and (p^ and 2 <> 0) and (p^ and $80000000 = 0) and (p^ and $7FFFFFFC <> 0);
end;
var
p: PInteger;
begin
p := Pointer(Integer(Ptr)-4);
result := (Cardinal(Ptr) > $FFFF) and not IsBadReadPtr(p, 8) and (p^ and 2 <> 0) and (p^ and $80000000 = 0) and (p^ and $7FFFFFFC <> 0);
end;
解决方案 »
- 如何将dbgird某个字段值赋值给变量
- 大家一起帮忙解决数据库分析问题.(择优)
- 请推荐网络编程的入门书籍,谢了.
- 可以用Delphi绘制三维图形吗?
- BMP转换成 emf或 wmf格式????????????
- 请问在Delphi里如何屏蔽掉鼠标滚轮.
- 我用ado连接数据库,提示错误“OLE error 80030002”,这是什么意思?
- 关于,如何让程序在后台执行的问题!!!在线等待!!
- 怎样实现在Delphi对DOS命令(如net)的调用?(100分)
- 如何写存储过程得到给定字段类型的长度
- 刚刚升级到borland官方网站的Delphi 2006的update1,问:为什么Delphi 2006完整支持VB.net开发????
- VC代码转Delphi?
1. windows中有效pointer指针的值都大于64k
2. IsBadReadPtr是windows的api, 判断应用程序是否有权限读某个地址和长度的内存
3. 在1和2满足的情况下说明内存是delphi的memory manager可以访问的,此时可以读取memory manager分配的内存的控制字段以判断该块内存是否有效,该控制字段是一个整数,位于Ptr-4位置,低两位和最高位是标记,剩下的位组成了内存块的长度。最低位标识了memory manager的内存链表中前一块内存是否已释放,最低第二位标识了本块内存是否已占用带注释的代码在这:function IsValidMemPtr(Ptr: Pointer): Boolean;
var
p: PInteger;
begin
p := Pointer(Integer(Ptr)-4); // 指向内存控制字段
result := (Cardinal(Ptr) > $FFFF) and not IsBadReadPtr(p, 8) //至少控制字段及内存前4个字节(delphi动态分配的内存是4字节的整数倍,最少12字节)是有效可访问地址
and (p^ and 2 <> 0) // 内存块被占用
and (p^ and $80000000 = 0) //未被充填
and (p^ and $7FFFFFFC <> 0); // 内存块长度<> 0
end;这段代码是有使用限制的,不过可以适应90%的应用(尤其是可以判断某个对象是否已释放)。它不能判断指向栈中的指针是否有效,也不能判断指向某块内存中间某个地址的指针是否有效。比如这段代码不能判断如下情况:procedure test;
var
buffer: array [0..100] of char;
p, p1: Pointer;
begin
p := @buffer;
getmem(p1, sizeof(buffer));
p1 := pointer(integer(p1)+50);
if IsValidMemPtr(p) then ... // 错误!无法判断栈中的指针是否有效
if IsValidMemPtr(p1) then ... // 错误!不能判断指向某块内存中间的地址是否有效
end;
我加到FAQ