对于非空的错误指针导致的崩溃,不能用常用的try{}catch{}进行处理,在C++中,这种方法只能处理异常,但对于空指针、除以0这些操作,不能算是异常,而是错误,是不能捕获并处理的;
非空的错误指针,通常是由试图访问了非法的内存或者写入了非法的内存导致的,比如说:访问损坏的dump文件里面的内容,会导致读取内存或模块列表出错;这时可选择使用Windows API函数来进行处理;
判断调用进程是否拥有对指定字符串指针的读取权限,函数原型如下:
BOOL IsBadStringPtr(
LPCTSTR lpsz,
UINT_PTR ucchMax);
参数:
lpsz: 输入参数,指向字符串。
ucchMax:输入参数,读取字符串的最大长度。
返回值:
返回BOOL值,表示当前进程是否拥有字符串指针指向的字符串的度操作权限。
IsBadWritePtr
判断调用进程是否拥有对指定地址段内存的写操作权限,函数原型如下:
BOOL IsBadWritePtr(
LPVOID lp,
UINT ucb);
参数:
lp: 输入参数,指向起始内存地址。
ucb: 输入参数,从起始内存地址开始的内存块的长度。
返回值:
返回BOOL值,表示当前进程是否拥有字符串指针指向的字符串的写入权限。
验证调用进程具有写访问权限的指定范围的内存。
lp 第一个字节的内存块的指针。
ucb 指定的大小,单位为字节的内存块。如果此参数为零,则返回值为零。
返回值
零 调用进程在指定的内存范围具有写访问权限的所有字节。
非零 调用进程在指定的内存范围内没有写访问权限的所有字节。
IsBadReadPtr
函数原型:
BOOL IsBadReadPtr(CONST VOID *lp,UINT_PTR ucb);
参数:
lp 表示要检查的内存指针
ucb 要检查的内存块的大小
返回:
如果调用进程有权限访问该内存,返回0
否则,返回非0
说明:
该函数检查调用进程是否有读取指定内存的内容的权限,微软提供的32位操作系统下的API
BOOL IsBadReadPtr(
const VOID* lp,
UINT_PTR ucb
);
验证调用进程具有读访问权限的指定范围的内存。
lp 第一个字节的内存块的指针。
ucb 指定的大小,单位为字节的内存块。如果此参数为零,则返回值为零。
返回值
零 调用进程在指定的内存范围具有读访问权限的所有字节。
非零 调用进程在指定的内存范围内没有读访问权限的所有字节。
关于如何获取指针内存块的长度:
这里介绍一个不常见到的函数,即:_msize()。其原型为:size_t _msize( void * memblock );
一般我们要返回某个类型的数据所占用的内存首先是考虑 sizeof() 和 strlen() 函数,但对于用 new 分配出来的内存来说如:char * pc = new char[10] ; 想返回 pc 所指向的内存的大小,sizeof(pc), 或strlen(pc) 都是得不到所需要结果的,因为 sizeof() 返回的是指针本身所占用内存的大小,strlen() 只能用char*做参数,且必须是以''\0''结尾的。
而_msize() 函数则可以返回用 new 方式分配出来的内存大小。如下所示:
char * pc = new char[10] ;
int n = _msize(pc) / sizeof(char);
最后得到的结果是 n = 10。
(1)函数原型
size_t _msize(
void* memblock
);
(2)函数说明
1)参数memblock为一个堆内存块的地址。不能传入栈上的地址(例如a[10],_msize(a))
2)函数返回指针所指内存块的大小。malloc分配的函数返回的地址不包含首部,因此使用_msize()函数测得的也不包含首部大小。
注意:这个函数需要头文件:#include<malloc.h>对于不能读取到的堆内存无法使用,否则会导致崩溃。