分享

嵌入式系统中堆heap和栈stack的管理——如何避免heap使用的错误

 oskycar 2013-11-20
2. Heap的包装数据组织以检测是否heap被破坏

2中的size域值是用于free()函数来找到该魔幻数字的,如下面的实例代码所示。包装函数用8个字节的额外开销来记载heap的结构。下例重新实现了C++中的newdelete函数。 

#include <stdint.h>
#include <stdlib.h>
#define MAGIC_NUMBER 0xefdcba98
uint32_t myMallocMaxMem;

void* MyMalloc(size_t bytes)
{
   uint8_t *p, *p_end;
   static uint8_t* mLow = (uint8_t*)0xffffffff; /* lowest address  
   returned by malloc() */
   static uint8_t* mHigh; /* highest address + data returned by 
   malloc() */
   bytes = (bytes + 3) & ~3; /* ensure alignment for magic number */
   p = (uint8_t*)malloc(bytes + 8); /* add 2x32-bit for size and 
   magic number */
   if (p == NULL)
   {
      abort(); /* out of memory */
   }
   *((uint32_t*)p) = bytes; /* remember size */
   *((uint32_t*)(p + 4 + bytes)) = MAGIC_NUMBER; /* write magic number after user allocation */
   /* crude method of estimating maximum used size since application start */
   if (p < mLow) mLow = p;
   p_end = p + bytes + 8;
   if (p_end > mHigh) mHigh = p_end;
   myMallocMaxMem = mHigh - mLow;
   return p + 4; /* allocated area starts after size */
}

void MyFree(void* vp)
{
   uint8_t* p = (uint8_t*)vp - 4;
   int bytes = *((uint32_t*)p);
   /* check that magic number is not corrupted */
   if (*((uint32_t*)(p + 4 + bytes)) != MAGIC_NUMBER)
   {
      abort(); /* error: data overflow or freeing already freed 
      memory */
   }
   *((uint32_t*)(p + 4 + bytes)) = 0; /* remove magic number to be 
   able to detect freeing already freed memory */
   free(p);
}

#ifdef __cplusplus
// global override of operator new, delete, new[] and delete[]
void* operator new (size_t bytes) { return MyMalloc(bytes); } 
void operator delete (void *p) { MyFree(p); }
#endif

需要说明的是,上面的实例能避免之前提到的错误是在分配的内存也被释放的前提下。但有些应用并不如此,这就需要添加另外的域来维护当前系统中分配的内存区域,然后周期性的验证分配内存记录的合理性。这个附加的列示当前动态内存分配的表不会太长因为对于嵌入式系统而言,只需要使用次数相对较少的动态内存。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多