动态申请内存与释放时的异常---Byte越界(CheckBytes函数的内部机制)
来源:互联网 发布:手机淘宝卖家账号注册 编辑:程序博客网 时间:2024/06/05 16:39
今天在堆代码的时候,堆了下面一段代码,Debug时异常,Release没问题。
const std::string &sFilename;wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(sFilename.length()-1)); m_hDLL = ::LoadLibrary(/*stringToLPCWSTR(sFilename)*/stringToLPCWSTR(sFilename,wcstring)); if (wcstring) { delete []wcstring; } wcstring = NULL;其实很简单,得到一个const std::string &类型的参数sFilename,想通过它来加载dll,但是::LoadLibrary的参数是LPCWSTR类型,就自己写个函数
LPCWSTR stringToLPCWSTR(std::string orig, wchar_t * wcstring)
来转换一下。
然后就在转换前动态申请了内存,并在使用后释放,如下:
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(sFilename.length()-1));....................................... if (wcstring) { delete []wcstring; } wcstring = NULL;看起来貌似没问题,但是Debug异常了,问题出在delete []wcstring;这句,果断跟进去,最后跟进n层后定位到下面这个函数
extern "C" static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize ){ int bOkay = TRUE; while (nSize--) { if (*pb++ != bCheck) {/* Internal error report is just noise; calling functions all report results - JWM *//* _RPT3(_CRT_WARN, "memory check error at 0x%p = 0x%02X, should be 0x%02X.\n", *//* (BYTE *)(pb-1),*(pb-1), bCheck); */ bOkay = FALSE; } } return bOkay;}
这个函数的作用是检查指定范围内的Byte是否被更改,如果被更改,返回false,如果未更改,返回true;
第一个参数是一个指针,第二个参数是用来进行比较的值,第三个参数是从指定位置(第一个指针表示)起,检测的位数。调试发现,bCheck为253,对应16进制为fd,nSize为4,下面查看内存,如图:
可以看到第一行中连续6个ab的前面有3个连续的00 ,其中第一个00是与其左边的6e共同组成一个Unicode宽字符,对应字符n,后两个连续的00组成宽字符\0,也就是从这个位置开始,CheckByte函数开始向后检测4位,看其是否是fd,由图可知,显然不是,所以返回false,抛出异常
下面,如果我申请的内存这么写:
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(sFilename.length()-1)+2);
即多申请两个字节,内存图如下:可以看到连续的00后只有2个fd,调试仍然失败
下面,多申请4个字节:
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(sFilename.length()-1)+4);
可以看到现在内存中连续的00后有了四个fd,调试不再抛异常。
最后,在以上三种情况下,通过查看CheckByte的第一个参数pb发现,pb总是我们申请的内存空间的末尾位置向前移动2个字节(如果算上编译器自动加上的用于存放\0的2个字节,那就是向前移动4个字节)。也就是说,如果我们申请的内存不足够大,那么编译器将无法在其末尾找到连续4个fd,他就会认为内存越界而异常。
经验就是,在使用宽字符的时候多申请一些空间,最小也得多申请4个。
char的时候没试验,应该也是同样的道理。
- 动态申请内存与释放时的异常---Byte越界(CheckBytes函数的内部机制)
- 动态申请内存与释放时的异常---Byte越界(CheckBytes函数的内部机制)
- 释放动态申请的内存
- 内存的申请与释放
- 内存的申请与释放
- malloc与free 动态内存的申请与释放
- 多维数组的内存动态申请与释放
- 动态内存申请与释放
- 关于动态内存的申请和释放
- 内存申请的释放
- malloc,free动态申请释放内存机制
- C和C++动态内存的申请与释放思考(动态多维数组空间分配)
- DLL中申请内存及释放的机制。
- c语言中动态内存申请与释放的简单理解
- C语言动态内存的申请与释放及野指针
- 良好的动态内存申请和释放习惯
- 内存(堆)的动态申请和释放
- 内存的申请和释放
- c++ volatile用法
- Postgres常用命令总结
- Java内联函数
- java swing 中使用JFileChooser读取Excel并进行解析
- 使用JMS接口接入WebSphere MQ消息
- 动态申请内存与释放时的异常---Byte越界(CheckBytes函数的内部机制)
- Java web开发中读取资源文件
- Android2.3 中如何使用GPU硬件加速
- cannot open file "mfc42u.lib"的解决方案
- oracle dba系统管理的有用sql
- 选择排序,冒泡排序和插入排序使用时间的对比
- centos 硬盘读写速度问题测试
- 迷你路由器设置
- CollectionBase的使用方法