前景 :在我之前一篇文章中测试的第三点,探讨了堆(HEAP)空间内,对于malloc申请实际使用大小的探讨(可能有不严谨的地方),基于原本的malloc和free函数,进行封装,使得弄够在代码中检测堆是否溢出(自测无太大用处,但确实好用,以防万一出现问题)
https://blog.csdn.net/yanjuezheng/article/details/130224415?spm=1001.2014.3001.5502
先上代码 :
#define Heap_Size (0x200)
static uint32_t __heap_rema = Heap_Size - 0x08;
/**
* @brief Space request function
* @param uint32_t malloc size
* @retval void* data type
*/
void *tool_Malloc(uint32_t size)
{
uint32_t act_size = (size / 0x08 + 0x01) * 0x08 + ((size % 0x08 > 0x04) ? 0x08 : 0x00);
if(act_size > __heap_rema)
{
log_err("tool_Malloc size too long and the __heap_rema is %08X, the act_size is %04X", __heap_rema, act_size);
return NULL;
}
__heap_rema -= act_size;
log_info("__heap_rema = %08X", __heap_rema);
return malloc(size);
}
/**
* @brief Space release function
* @param void* data type
* @retval void
*/
void tool_Free(void *ptmp)
{
__heap_rema += (uint32_t)*((uint8_t *)ptmp - 0x04);
log_info("tool_Free len = %08X", (uint32_t)*((uint8_t *)ptmp - 0x04));
free(ptmp);
}
1.首先第一个宏定义,Heap_Size 需要用户自行确认填写堆空间大小,不了解的伙伴可以去startup_stm32fxxxxxxx.s文件去查看,如下图所示
2. __heap_rema 为实际剩余空间大小,减去不可使用的起始0x08个字节
3.tool_Malloc中参数size为用户申请空间大小,而act_size计算得到的是实际申请得到的空间大小,这个是可以验证得到的
4.对于tool_Free函数而言,*ptmp为要释放的指针,(uint32_t)*((uint8_t *)ptmp - 0x04);这个表达式就是说明用户实际使用申请到的指针前面四个字节就是存放该用户申请得到的实际空间大小,这里得到的值跟上一点中计算出来的act_size是完全一致的
以使用链表和cjson为例,看看实际的效果:
结论 :采用1字节对齐的方式,该结构体长度如图所示22个字节,但在实际空间申请的时候计算出来的act_size是0x20,也就是32个字节,最后空间释放的时候,能够得到实际上释放和申请的空间确实是0x20(32)个字节
结语 :随便写写,有用,但不多