帮助调试内存错误的方法一:
对已经分配或者释放的内存写入确定的字节作为标识,以帮助暴露程序中的错误:
0xCD 已经分配的数据 alloCated Data
0xDD 已经释放的数据 Deleted Data
0xFD 被保护的数据 Fence Data
其中保护字节被写入在被保护内存区域的开始和结束的四个字节,以帮助检测上溢出和下溢出。
举例说明:
//pData被设为0xCDCDCDCD
float *pData = new float;
//fence1和fence2被设为0xFDFDFDFD
int fence1 = *((int*)pData) -1;
int fence2 = *(int*)(((char*)pData)+sizeof(float));
delete pData;//执行后pData被设为0xDDDDDDDD。
(如果你没有选中调试堆选项中的_CRTDBG_DELAY_FREE_MEM_DF,而且打算重新计算fence1和fence2的值,就会发现他们也被设成0xDDDDDDDD。)
这样做的好处
如果你发现一个程序尝试对一个内容为0xCDCDCDCD或者0xDDDDDDDD的指针地址解除引用(或者类似的标识,如0xCDCDCDF0很可能是由某个错误指针加上偏移),这时候一定是发现了一个程序错误。
帮助调试内存错误的方法二:
另一种方法是C运行时刻函数库使用的内存块类型标识符。虽然前面的字节标识法很有用,但是不能以规则的方式对它们进行检查。
内存块类型:
_NOMAL_BLOCK 由程序直接分配的内存
_CLIENT_BLOCK 由程序直接分配的内存,可以通过内存调试函 数对其拥有特殊控制权
_CRT_BLOCK 由运行时刻函数库内部分配的内存
_FREE_BLOCK 已经被释放,但是跟踪仍然被保留下来的内存 ,这在用户选择了调试堆选项 _CRTDBG_DELAY_FREE_MEM_DF以后会出现
_IGNORE_BLOCK 当使用_CrtDbgFlag关闭内存调试操作以后分 配的内存(内存调试函数不会对这些内存块进 行检查,认为它们没有错误)
还要注意一点就是这些调试函数只能在调试版本中使用。
一些有用的内存调试函数略。
使用调试堆
一.使用条件与目的:
1.确定自己使用的是程序的调试版本,并且链接的是C运行时刻函数库的调试版本;
2.必须定义_DEBUG;
这样调试堆版本的new和delete才会被调用,才能检测内存错误和内存泄漏。
3.选择所需要的额外测试选项,在程序结束的时候显示内存 ,正确报告源文件名和行号,并且显示数据信息;
二.调试堆选项
用户使用_CrtSetDbgFlag函数对调试堆的检查工作进行控制。
调试堆选项略。
对已经分配或者释放的内存写入确定的字节作为标识,以帮助暴露程序中的错误:
0xCD 已经分配的数据 alloCated Data
0xDD 已经释放的数据 Deleted Data
0xFD 被保护的数据 Fence Data
其中保护字节被写入在被保护内存区域的开始和结束的四个字节,以帮助检测上溢出和下溢出。
举例说明:
//pData被设为0xCDCDCDCD
float *pData = new float;
//fence1和fence2被设为0xFDFDFDFD
int fence1 = *((int*)pData) -1;
int fence2 = *(int*)(((char*)pData)+sizeof(float));
delete pData;//执行后pData被设为0xDDDDDDDD。
(如果你没有选中调试堆选项中的_CRTDBG_DELAY_FREE_MEM_DF,而且打算重新计算fence1和fence2的值,就会发现他们也被设成0xDDDDDDDD。)
这样做的好处
如果你发现一个程序尝试对一个内容为0xCDCDCDCD或者0xDDDDDDDD的指针地址解除引用(或者类似的标识,如0xCDCDCDF0很可能是由某个错误指针加上偏移),这时候一定是发现了一个程序错误。
帮助调试内存错误的方法二:
另一种方法是C运行时刻函数库使用的内存块类型标识符。虽然前面的字节标识法很有用,但是不能以规则的方式对它们进行检查。
内存块类型:
_NOMAL_BLOCK 由程序直接分配的内存
_CLIENT_BLOCK 由程序直接分配的内存,可以通过内存调试函 数对其拥有特殊控制权
_CRT_BLOCK 由运行时刻函数库内部分配的内存
_FREE_BLOCK 已经被释放,但是跟踪仍然被保留下来的内存 ,这在用户选择了调试堆选项 _CRTDBG_DELAY_FREE_MEM_DF以后会出现
_IGNORE_BLOCK 当使用_CrtDbgFlag关闭内存调试操作以后分 配的内存(内存调试函数不会对这些内存块进 行检查,认为它们没有错误)
还要注意一点就是这些调试函数只能在调试版本中使用。
一些有用的内存调试函数略。
使用调试堆
一.使用条件与目的:
1.确定自己使用的是程序的调试版本,并且链接的是C运行时刻函数库的调试版本;
2.必须定义_DEBUG;
这样调试堆版本的new和delete才会被调用,才能检测内存错误和内存泄漏。
3.选择所需要的额外测试选项,在程序结束的时候显示内存 ,正确报告源文件名和行号,并且显示数据信息;
二.调试堆选项
用户使用_CrtSetDbgFlag函数对调试堆的检查工作进行控制。
调试堆选项略。