void* _GetBusyNode(void* addr)
{
 if ( g_busyList == NULL)
 {
  return NULL;
 }
 if ( NULL == g_busyList->next)
 {
  MemoryInfo* retNode = NULL;
  if (g_busyList->data->addr == addr)
  {
   retNode = g_busyList->data;
            delete g_busyList;
   g_busyList = NULL;           
  }
 
  return (void*)retNode;
 }
 BusyList* pre ?? *curr;
 pre = curr = g_busyList;
 while(curr)
 {
  if (curr->data->addr == addr)
  {
   BusyList* tmp = curr;
   MemoryInfo* retNode = curr->data;
   pre->next = curr->next;
   free((void*)tmp);
   return (void*)retNode;
  }
  pre = curr;
  curr = curr->next;
 }
    return NULL;
}
void _FreeNode(void* p)
{
    if ( NULL == p)
    {
        return;
    }
    FreeList* tmpNode = (FreeList*)p;
    tmpNode->next = g_freeList;
    g_freeList = tmpNode;
}
//?????????????
void _StoreMemoryAllocInfo(void* addr ?? size_t size ?? _UL lineNum ?? const char* file)
{
    MemoryInfo* node = (MemoryInfo*)_GetFreeNode();
    if ( NULL == node )
    {
        return;
    }
    node->addr =addr;
    node->size = size;
    node->lineNum = lineNum;
  
    size_t len = strlen(file);
    len = len >= MAX_FILE_LEN ? MAX_FILE_LEN - 1 : len;
    strncpy(node->fileName ?? file ?? len);
 node->fileName[len] = '/0';
    //????????
    BusyList* busyNode = (BusyList*)malloc(sizeof(BusyList));
    busyNode->data = node;
    if ( g_busyList == NULL )
    {
        g_busyList = busyNode;
        busyNode->next = NULL;
    }
    else
    {
        busyNode->next = g_busyList;
        g_busyList = busyNode;
    }
    //д?????
    _WriteMemoryInfo(node ?? true);
}
//?????????????
void _StoreMemoryDeallocInfo(void* addr)
{
 MemoryInfo* node = (MemoryInfo*)_GetBusyNode(addr);
 if ( NULL == node )
 {
  return;
 }
 //д?????
 _WriteMemoryInfo(node ?? false);
    _FreeNode((void*)node); 
}
//д???????
void _WriteMemoryInfo(const MemoryInfo* pInfo ?? bool bAlloc)
{
    if (pInfo != NULL)
    {
        FILE *fp = fopen("debugmemorylog.txt"??"a+");
        if (!fp)
            return;
        fprintf(fp??"%p:/t%s/t%d line %s %d bytes/n"??pInfo->addr?? pInfo->fileName?? pInfo->lineNum /
            ?? (bAlloc ? "allocated" : "freed") ?? pInfo->size);
        fflush(fp);
        fclose(fp);
    }
}
//??й?????????д??????
void DumpLeakedMemoryInfo()
{
 FILE *fp = fopen("memoryleak.txt"??"a+");
 if (!fp)
  return;
 
 BusyList* p = g_busyList;
 while (p)
 {
  BusyList* tmp = p;
  MemoryInfo* pInfo = tmp->data;
  if (pInfo != NULL)
  {   
   fprintf(fp??"%p:/t%s/t%d line leak %d bytes/n"??pInfo->addr?? pInfo->fileName?? pInfo->lineNum ?? pInfo->size);   
  }
  _FreeNode((void*)pInfo);
       delete tmp;
    tmp = NULL;
    p = p->next;
 }
 fflush(fp);
 fclose(fp);
 //??????????????????
    _ReleaseFreeList();
}
void _ReleaseFreeList()
{
    while(g_freeList)
 {
  FreeList* tmp = g_freeList->next;
  delete g_freeList;
  g_freeList = tmp;  
 }
}
#endif//DETECT_MEMORY_LEAK