常见的debug error
了解堆空间的产生与销毁:
申请堆空间的过程中调用了函数_heap_alloc_dbg,其中使用了_Crt_Mem_BlockHeader结构描述了堆空间中的各个成员,在内存中堆结构的每个节点都是使用双向链表的形式存储的,在_Crt_Mem_BlockHeader中定义了前指针pBlockHeaderPrev和后指针pBlockHeaderNext,通过这两个指针就可遍历程序中所有申请的堆空间,成员IRequest记录了当前堆是第几次申请的,例如第10次申请即为0x0A,成员gap为保存堆数据的数组,在Debug版下,这个数据的前后4个字节被初始化为0xFD,用于检测堆数据访问过程中是否有越界访问,
typedef struct _Crt_Mem_BlockHeader
{
struct _Crt_Mem_BlockHeader* pBlockHeaderPrev;/*上一块内存空间首地址*/
struct _Crt_Mem_BlockHeader* pBlockHeaderNext;/*下一块内存空间首地址*/
unsigned char gap[noNomanslandSize];/*堆空间数据*/
char* szFileName;
int nLine;
size_t nDataSize; /*堆空间数据大小位于低地址0A*/
int nBlockUse;
long lRequesr; /*申请次数0x2A位于高地址*/
}_Crt_Mem_BlockHeader
在释放过程中,根据堆数据的首地址将所释放的堆从链表中脱链,完成操作。
堆数据地址减4后数据为0xfdfdfdfd,往上越界的标志
**回收利用:**当某个堆空降释放后,再次申请堆空间会检查这个被释放的堆空间是否能满足用户要求,如果能满足,则再次申请的堆空间地址将会是刚释放的堆空间地址,这就形成了回收空间的再次利用。